1. 程式人生 > >Java中常用的異常處理情況課件動手動腦

Java中常用的異常處理情況課件動手動腦

1:請閱讀並執行AboutException.java示例,然後通過後面的幾頁PPT瞭解Java中實現異常處理的基礎知識。

import javax.swing.*;

class AboutException {
public static void main(String[] a)
{
int i=1, j=0, k;
k=i/j;
try
{

k = i/j; // Causes division-by-zero exception
//throw new Exception("Hello.Exception!");
}

catch ( ArithmeticException e)
{
System.out.println("被0除. "+ e.getMessage());
}

catch (Exception e)
{
if (e instanceof ArithmeticException)
System.out.println("被0除");
else
{
System.out.println(e.getMessage());

}
}


finally
{
JOptionPane.showConfirmDialog(null,"OK");
}

}
}

執行結果如下:

Java中把可能會發生錯誤的程式碼放進try語句塊中。 當程式檢測到出現了一個錯誤時會丟擲一個異常物件。異常處理程式碼會捕獲並處理這個錯誤。 catch語句塊中的程式碼用於處理錯誤。 當異常發生時,程式控制流程由try語句塊跳轉到catch語句塊。 不管是否有異常發生,finally語句塊中的語句始終保證被執行。 如果沒有提供合適的異常處理程式碼,JVM將會結束掉整個應用程式。

Throwable類有兩個直接子類: Exception:出現的問題是可以被捕獲的; Error:系統錯誤,通常由JVM處理。 可捕獲的異常又可以分為兩類: (1)Check異常:直接派生自Exception的異常類,必須被捕獲或再次宣告丟擲 (2)Runtime異常:派生自RuntimeException的異常類。使用throw語句可以隨時丟擲這種異常物件: throw new ArithmeticException(…);

JDK1.4 以上提供了assert語句,允許程式在執行期間判斷某個條件是否滿足,不滿足時,丟擲AssertionError

預設情況下,assert功能是關閉的,可以在使用java啟動JVM時新增引數-ea開啟它。

2:int i=1, j=0, k; k=i/j;程式碼在執行時 會引發異常,而double d1=100,d2=0,result; result=d1/d2; System.out.println("浮點數除以零:" + data);不會引發異常,原因是什麼?

JVM在具體實現這兩個程式的位元組碼指令時,採用了不同的處理策略,所以會導致兩段程式碼執行時得到不同的結果。

可以有多個catch語句塊,每個程式碼塊捕獲一種異常。在某個try塊後有兩個不同的catch 塊捕獲兩個相同型別的異常是語法錯誤。 使用catch語句,只能捕獲Exception類及其子類的物件。因此,一個捕獲Exception物件的catch語句塊可以捕獲所有“可捕獲”的異常。 將catch(Exception e)放在別的catch塊前面會使這些catch塊都不執行,因此Java不會編譯這個程式。

“finally”的功用:資源洩露:當一個資源不再被某應用程式使用,但此程式並未向系統宣告不再使用此資源時發生這種情況 finally語句塊主要用於解決資源洩露問題,它位於catch語句塊之後,JVM保證它們一定執行。 注意:finally語句塊中也可能發生異常,如果這種情況發生,先前的異常被放棄。

3:閱讀以下程式碼(CatchWho.java),寫出程式執行結果以及寫出CatchWho2.java程式執行的結果。再閱讀EmbedFinally.java示例,再執行它,觀察其輸出並進行總結。:

public class CatchWho {
public static void main(String[] args) {
try {
try {
throw new ArrayIndexOutOfBoundsException();
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println( "ArrayIndexOutOfBoundsException" + "/內層try-catch");
}

throw new ArithmeticException();
}
catch(ArithmeticException e) {
System.out.println("發生ArithmeticException");
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println( "ArrayIndexOutOfBoundsException" + "/外層try-catch");
}
}
}

執行結果如下:

public class CatchWho2 { 

public static void main(String[] args) {
try {
try {
throw new ArrayIndexOutOfBoundsException();
}
catch(ArithmeticException e) {
System.out.println( "ArrayIndexOutOfBoundsException" + "/內層try-catch");
}
throw new ArithmeticException();
}
catch(ArithmeticException e) {
System.out.println("發生ArithmeticException");
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println( "ArrayIndexOutOfBoundsException" + "/外層try-catch");
}
}
}

執行結果如下:

public class EmbededFinally {


public static void main(String args[]) {

int result;

try {

System.out.println("in Level 1");


try {

System.out.println("in Level 2");
// result=100/0; //Level 2

try {

System.out.println("in Level 3");

result=100/0; //Level 3

}

catch (Exception e) {

System.out.println("Level 3:" + e.getClass().toString());

}


finally {

System.out.println("In Level 3 finally");

}


// result=100/0; //Level 2


}

catch (Exception e) {

System.out.println("Level 2:" + e.getClass().toString());

}
finally {

System.out.println("In Level 2 finally");

}

// result = 100 / 0; //level 1

}

catch (Exception e) {

System.out.println("Level 1:" + e.getClass().toString());

}

finally {

System.out.println("In Level 1 finally");

}

}

}

執行結果如下:

所以當有多個巢狀的try…catch…finally時,要特別注意finally的執行時機。

當有多層巢狀的finally時,異常在不同的層次丟擲 ,在不同的位置丟擲,可能會導致不同的finally語句塊執行順序。

4:finally語句塊一定會執行嗎?

public class SystemExitAndFinally {


public static void main(String[] args)
{

try{


System.out.println("in main");

throw new Exception("Exception is thrown in main");

//System.exit(0);


}

catch(Exception e)

{

System.out.println(e.getMessage());

System.exit(0);

}

finally

{

System.out.println("in finally");

}

}


}

執行結果如下:

如果在try程式碼塊之前就結束了temp()方法,try程式碼塊並沒有得到執行,所以finally中的程式碼塊也不會得到相應的執行。只有在try程式碼塊得到執行的情況下,finally程式碼塊才會得到執行。如果當一個執行緒在執行 try 語句塊或者 catch 語句塊時被打斷(interrupted)或者被終止(killed),與其相對應的 finally 語句塊可能不會執行。還有更極端的情況,就是線上程執行 try 語句塊或者 catch 語句塊時,突然宕機或者斷電,finally 語句塊肯定不會執行了。