工作時,一直對try塊中throw的異常對象,在catch中如何處理此異常,以及trycatchfinally完畢,程序是否就此停止還是繼續運行很迷惑,於是參考網上的資料,自己寫了些demo,去慢慢探索。
例1.
1 public static void main(String[] args) { 2 int i = 7; 3 int j = 0; 4 try { 5 if (j == 0) 6 throw new ArithmeticException(); 7 System.out.println("打印計算結果i/j=" + i / j); 8 } 9 catch (ArithmeticException e) { 10 System.out.println("被除數j不能等於0"); 11 } 12 System.out.println("運行結束"); 13 }
run:
被除數j不能等於0
運行結束
結論:可以看到,當try塊中創建 ArithmeticException異常對象,並由throw語句將異常拋給Java運行時系統,由系統尋找匹配的異常處理器catch並運行相應異常處理代碼,打印 "被除數j不能等於0",然后trycatch塊結束,程序繼續運行,打印"運行結束".可以看到,throw 異常對象,程序並未結束,而是繼續執行。另外,我們在catch塊中用輸出語句打印信息,並不能很全面,直觀,專業的把異常信息給顯示出來。
例2.
1 public static void main(String[] args) { 2 int i = 7; 3 int j = 0; 4 try { 5 if (j == 0) 6 throw new ArithmeticException(); 7 System.out.println("打印計算結果i/j=" + i / j); 8 } 9 catch (ArithmeticException e) { 10 e.printStackTrace(); 11 } 12 System.out.println("運行結束"); 13 }
run:
java.lang.ArithmeticException
at com.westward.Demo4.main(Demo4.java:9)
運行結束
結論:通過catch塊中,調用異常對象ArithmeticException的printStackTrace()方法,能夠將對應的異常信息打印出來,trycatch塊下面的程序繼續執行。
例3.
如果我們想在try塊中,j==0時,程序拋出異常,並且程序中斷,可以繼續看下面的demo。
1 public static void main(String[] args) { 2 int i = 7; 3 int j = 0; 4 try { 5 if (j == 0) 6 throw new ArithmeticException(); 7 System.out.println("打印計算結果i/j=" + i / j); 8 } 9 catch (ArithmeticException e) { 10 throw e; 11 } 12 System.out.println("運行結束"); 13 }
run:
Exception in thread "main" java.lang.ArithmeticException
at com.westward.Demo4.main(Demo4.java:9)
結論:通過運行結果,我們可以看到,在catch塊中throw ArithmeticException對象后,throw語句將異常拋給Java運行時系統,由系統尋找匹配的異常處理器catch,由於未找到相應的異常處理器catch(沒有catch或者有catch,但是類型不符合),所以異常最后拋給了jvm,並在后台打印異常信息,程序在此中斷,trycatchfinally下面的程序代碼不在執行。
附加:事實上,ArithmeticException為RuntimeException(運行時異常,不可查異常)的子類。而運行時異常將由運行時系統自動拋出,不需要程序員使用throw語句顯示拋出。
下兩例摘自:http://blog.csdn.net/hguisu/article/details/6155636
感覺真是太經典了。
例子1:
1 public static void main(String[] args) { 2 int[] intArray = new int[3]; 3 try { 4 for (int i = 0; i <= intArray.length; i++) { 5 intArray[i] = i; 6 System.out.println("intArray[" + i + "] = " + intArray[i]); 7 System.out.println("intArray[" + i + "]模 " + (i - 2) + "的值: " 8 + intArray[i] % (i - 2)); 9 } 10 } catch (ArrayIndexOutOfBoundsException e) { 11 System.out.println("intArray數組下標越界異常。"); 12 } catch (ArithmeticException e) { 13 System.out.println("除數為0異常。"); 14 } 15 System.out.println("程序正常結束。"); 16}
run:
intArray[0] = 0
intArray[0]模 -2的值: 0
intArray[1] = 1
intArray[1]模 -1的值: 0
intArray[2] = 2
除數為0異常。
程序正常結束。
相信很多man會和我有一樣的疑問,怎么只拋出了ArithmeticException 異常,而未拋出ArrayIndexOutOfBoundsException異常呢?
答案是: 一旦某個catch捕獲到匹配的異常類型,將進入異常處理代碼。一經處理結束,就意味着整個try-catch語句結束。其他的catch子句不再有匹配和捕獲異常類型的機會。也就是說,jvm運行.class文件遇到異常時,只會拋出一種異常,這時這個trycatch塊就結束了。上例中,程序首先執行到i=2,除數為0的情況,java運行時程序將ArithmeticException 這個運行時異常拋給對應的catch異常捕捉器,執行異常代碼,打印 "除數為0異常。"。然后此trycatch塊結束,由於for循環在try塊中,所以第4此循環不在執行。所以不會遇到 ArrayIndexOutOfBoundsException。 接着打印 "程序正常結束。"。
例子2:
1 public static void main(String args[]) { 2 int i = 0; 3 String greetings[] = { " Hello world !", " Hello World !! ", 4 " HELLO WORLD !!!" }; 5 while (i < 4) { 6 try { 7 // 特別注意循環控制變量i的設計,避免造成無限循環 8 System.out.println (greetings[i]); 9 i++; 10 System.out.println(i); 11 12 } catch (ArrayIndexOutOfBoundsException e) { 13 System.out.println("數組下標越界異常"); 14 } finally { 15 System.out.println("--------------------------"); 16 } 17 } 18 }
run:
會死循環。
結論:當i=3的時候,jvm執行到 System.out.println (greetings[i]);@ 會拋異常,被 ArrayIndexOutOfBoundsException捕獲,執行catch塊里的代碼,然后執行finally,然后3<4,然后執行@處代碼,然后...原因就是當System.out.println (greetings[i]);拋異常的時候,它下面的代碼就不會執行了,所以i會永遠等於3,3<4永遠成立,進入死循環。
我們可以巧用finally如下例來避免這種情況發生。
1 public static void main(String args[]) { 2 int i = 0; 3 String greetings[] = { " Hello world !", " Hello World !! ", 4 " HELLO WORLD !!!" }; 5 while (i < 4) { 6 try { 7 // 特別注意循環控制變量i的設計,避免造成無限循環 8 System.out.println (greetings[i]); 9 10 System.out.println(i); 11 12 } catch (ArrayIndexOutOfBoundsException e) { 13 System.out.println("數組下標越界異常"); 14 } finally { 15 System.out.println("--------------------------"); 16 i++; 17 } 18 } 19 }
run:
Hello world !
0
--------------------------
Hello World !!
1
--------------------------
HELLO WORLD !!!
2
--------------------------
數組下標越界異常
--------------------------