1. 程式人生 > 實用技巧 >六、java 異常處理

六、java 異常處理

一、JAVA異常的體系結構
  ① Error:Java虛擬機器無法解決的嚴重問題;一般不編寫正對性的程式碼處理;
  ② Exception:其他因為程式設計錯誤或偶然的外在因素導致的一般性問題;可以進行異常處理;處理完後不影響程式的執行;

 a.Exception又可以分為執行時異常和編譯時異常;

 ①編譯時異常(check):編譯報錯,要求必須處理,否則編譯不通過;例如IOException、ClassNotFoundException

 ②執行時異常(unchecked RuntimExceprion):一般不處理;例如:NullPointerExcepion(空指標異常),ArrayIndexOutOfBoundsException(陣列越界異常),ClassCastExcetption(類轉換異常),NumberFormateException...

二、異常處理的兩種方式:

  ①不直接處理,往呼叫層丟擲異常 throw + 異常型別;

  ②處理異常:try{}catch(){}finally{}

一下為異常處理的throw的方式:丟擲異常,單元測試會報相應的NumberFormatException異常,無法執行到丟擲異常後的語句;

1     @Test
2     public void testx() {
3             String str = "abc";
4             int num = Integer.parseInt(str);
5             System.out.println("hello -1");
6 throw new NumberFormatException(); 7 //System.out.println("hello -2"); 8 }

一下為異常處理的try catch的方式:單元測試通過,並且執行了System.out.println("hello -2");

 1     @Test
 2     public void test1() {
 3         String str = "abc";
 4         try {
 5             
 6             int num = Integer.parseInt(str);
7 System.out.println("hello -1"); 8 }catch(NumberFormatException e) {//如果NumberFormatException換成時 NullPointerException則還是丟擲異常 9 System.out.println("出現數值轉換異常了。。。。"); 10 String mes = e.getMessage(); 11 System.out.println(mes);//常用異常處理方式1 12 e.printStackTrace();//常用異常處理方式2 13 14 } 15 System.out.println("hello -2"); 16 }

三、過程:

  過程一、“拋”;程式在正常執行過程中,一旦出現異常,就會在異常程式碼處生成一個對應異常的物件;並將此物件丟擲;
一旦丟擲異常,其後面的程式碼不再執行;
  關於異常物件的產生,1,系統生成 的,2.手動生成一個異常物件並且丟擲;throw;
  過程二:“抓”:可以理解為異常處理方式:

try catch finally的使用:
try{
//可能出現異常的程式碼
}catch(異常型別1 變數名){
//處理異常方式1
}catch(異常型別2 變數名){
//處理異常方式2
}catch(異常型別3 變數名){
//處理異常方式3
}
........
finally{
//一定會執行的程式碼
}
說明:
1.finaly 是可選的
2。使用try將肯出現的程式碼包裝起來,在執行過程中,一旦出現異常,就會生成一個對應異常類的物件,
根據此物件的型別,去catch中進行匹配
3.一旦try中的異常物件匹配到某一個catch時,就進入catch中進行異常處理,一旦處理完成就跳出try-catch結構(在沒有finally的情況),
繼續執行後面的程式碼;
4.catch中的異常型別如果沒有子父類關係,則誰宣告在上面,誰宣告在下,無所謂,
catch中的異常型別如果滿足子父類關係,則要求子類在上,父類在下,否則報錯;
5.常用的異常處理方式 a.String getMessage() ;b printStackTrace();
6.在try中宣告的變數,出了try結構就不能呼叫;
7.try catch finally 結構可以巢狀

例如:

@Test
    public void test2() {
        int a= 10;
        int b = 0;
        try {
            System.out.println(a / b); 
        } catch(ArithmeticException e){
            e.printStackTrace();
        }finally {
            System.out.println("finally~~~");
            // : handle finally clause
        }
    }

該程式 Junit通過,控制檯列印異常和finally~~~;因為程式執行到 System.out.println(a / b); b=0所以 出現了錯誤,生成ArithmeticException物件,與catch中的異常進行匹配,匹配上後,進行異常處理,處理完成,執行finally中的程式碼;

 1     @Test
 2     public void test3() {
 3 
 4         Day16ErrorAndExceptionDiscriable6 tt = new Day16ErrorAndExceptionDiscriable6();
 5         
 6         System.out.println(tt.finallyTest());
 7     }
 8 
 9 public int finallyTest() {
10     try {
11         int[] arr = new int[10];
12         //System.out.println(arr[10]); 開啟或者關閉,return都是3; 3之前是inally~~~
13         return 0;
14     } catch(ArrayIndexOutOfBoundsException e){
15         e.printStackTrace();
16         return 1;
17     }finally {
18         System.out.println("finally~~~");
19         return 3;
20         // : handle finally clause
21     }
22 }

必須要處理的異常:如若需要呼叫時,必須要處理異常,或者是再往上丟擲異常;

 1 public void method() throws FileNotFoundException,IOException{
 2     File file = new File("hello.txt");
 3     FileInputStream fis = null;
 4     fis = new FileInputStream(file);
 5     int data = fis.read();
 6     while(data != -1) {
 7         data = fis.read();
 8     }
 9     fis.close();
10 }
11 
12 public void method2() throws FileNotFoundException,IOException{
13             method();
14 }
 1 @Test
 2     public void test4() {
 3         File file = new File("hello.txt");
 4         FileInputStream fis = null;
 5         try {
 6             fis = new FileInputStream(file);
 7             int data = fis.read();
 8             while(data != -1) {
 9                 data = fis.read();
10             }
11         } catch (FileNotFoundException e) {
12             e.printStackTrace();
13         }catch (IOException e) {
14             e.printStackTrace();
15         }finally {
16             try {
17                 if(fis != null) {
18                     fis.close();
19                 }
20             } catch (IOException e) {
21                 // TODO Auto-generated catch block
22                 e.printStackTrace();
23             }
24         }
25         
26         
27     }

體會:

  try catch finally真正把異常處理掉,
  throws 的方式只是將異常拋給了方法的呼叫者,並沒有真正的處理掉異常

開發中,如何選擇try catch finally OR throws?
1.如果父類中被重寫的方法沒有throws,則子類重寫的方法也不能throws,意味著如果子類重寫的方法有異常,必須用try catch finally;
2.執行的方法A中,先後又呼叫了另外的幾個方法,這幾個方法是遞進的關係執行的,建議這幾個方法使用throws的翻翻,而執行的方法A可以考慮使用try catch finally;