java學習中,異常和錯誤的簡介、捕獲異常、拋出異常、自訂異常、finally關鍵字(java 學習中的小記錄),finally關鍵字
java學習中,異常和錯誤的簡介、捕獲異常、拋出異常、自訂異常、finally關鍵字(java 學習中的小記錄)
作者:王可利(Star·星星)
異常:(API 的 java.lang 有一個異常,有很多很多)
在Java程式中也會程式出現不正常的情況,這個就叫異常。
Java是物件導向的語言,任何事物都可以用類來描述,同樣的異常也是一種事物。Java中提供了很多的異常類。
多個異常堆積起來,就是一個異常體系。
Throwable:是異常類的父類,超類。Exception 異常、error錯誤。
異常的體系如下(圖解):
主要學習Thorwable 的三個方法:
1.toString(); 對Thorwable 的簡短描述:類完整的名稱: 包名 + 類名
2.getMessage(); Thorwable的詳細資料的字串
3.printStackTrace(); 列印的是異常的棧記憶體資訊
package study;public class star { public static void main(String[] args) { Throwable t = new Throwable("這是一個異常,請處理");//這裡是異常對象,所以異常//參數可以傳一個getMessage進來 System.out.println(t.toString());//java.lang.Throwable:這是一個異常,請處理 System.out.println(t.getMessage());//這是一個異常,請處理 t.printStackTrace();//列印的是異常的棧記憶體資訊 }}
error 錯誤:錯誤一般是Java虛擬機器或者硬體導致的問題,叫錯誤。所以我們一般不會用代碼來處理錯誤。
如:byte[] buf = new byte[1024*1024*1024];
//文法沒有錯誤,java虛擬機器預設只能管理64M記憶體,所以是因為java或者硬體引發的問題我們叫錯誤
異常Exception:所有的異常都 繼承於 Exception。
錯誤和異常的區別:
如:java.lang.OutOfMemoryError 這個是錯誤的一種類型(以Error結尾的)
AclNotFoundException 這個是一個異常(以Exception結尾,除了Error結尾的都是)
異常的處理:
方式一:捕獲異常
捕獲異常的處理格式:
try{
可能發生異常的代碼
}catch(捕獲的異常的類型 變數名){
處理異常的代碼
}
1 package study; 2 3 4 public class star { 5 public static void main(String[] args) { 6 7 int[] arr = {1,2}; 8 arr= null;//java.lang.NullPointerException null 指標異常 9 test(4, 0,arr);//java.lang.ArithmeticException: / by zero10 }11 public static void test(int a,int b,int[] arr){12 13 14 //捕獲異常處理15 int c = 0;16 17 try {18 //可能出現異常的代碼19 System.out.println(arr.length);20 c = a/b; 21 } catch (ArithmeticException e1) {22 System.out.println("處理除數為0的異常");23 } catch(NullPointerException e2){24 System.out.println("處理空制指標異常");25 } catch(Exception e){//這個父類的要放在最後面,如果放在最前面處理了異常了,後面的異常都不會執行了。這樣這個可以處理上面沒有的其他異常。26 System.out.println("所有的異常都在這裡處理");27 } 28 29 System.out.print("c = "+c);30 }31 }
捕獲異常處理的注意點:
1.如果try中的方法出了問題,處理之後會繼續執行try-catch 以外的代碼。
2.catch裡面的代碼只會在 try中的代碼出現異常了,才會執行。
3.一個try中是可以用很多個catch塊,也就是會說一個try可以處理很對個異常。
4.try 捕獲異常是從小到大的順序來的捕獲異常的。最下面的是父類最大的異常。否者就會報錯。
捕獲異常的作用:
目前還看不出,學習JavaEE的時候就經常用到(知識點後期補上);
為什麼不直接用最大的異常:
為了讓我們跟精確快速地找到錯誤的根源。如:null 指標異常,用最大的異常的話,就看不出來是null 指標異常。
方式二:拋出異常
拋出異常處理關鍵的兩個關鍵字(throw 、throws)
throw 、throws使用注意點:
1.throw 關鍵字用於方法裡面,throws 用於方法聲明上的。
2.throw 關鍵字用於方法內部拋出異常,throws 用於方法聲明上拋出異常。
3.throw 關鍵字後面只能有一個異常,throws 可以聲明多個異常。
拋出異常的使用注意點:
1.如果你在方法中拋出了一個異常對象,就必須在方法聲明上一個異常的拋出。
2.如果一個方法調用了拋出異常的方法,那麼調用者就必須處理拋出的這個異常。
3.如果一個方法中跑出了異常,那麼throw後面的代碼不會再被執行。
4.在一種情況下只能拋出一種異常。(詳見代碼)如果是多個異常的話,就取離它最近的那個異常。
什麼時候拋異常,什麼時候不拋異常?
需要通知調用者(誰調用你的代碼),你的代碼可能存在問題,,這個時候就需要拋出這個異常,讓調用者來解決處理。
如果代碼是直接和使用者打交道的,這個時候遇到異常,就需要處理代碼,使用者不知道這個代碼是什麼意思,要換個方式讓使用者知道這個是什麼。
1 package study; 2 3 4 public class star { 5 public static void main(String[] args) { 6 try { 7 int[] arr = {1,2}; 8 arr = null; 9 test(4, 0,arr);10 } catch (ArithmeticException e) {11 System.out.println("正在處理異常");12 }13 14 }15 public static void test(int a ,int b,int[] arr) throws ArithmeticException,NullPointerException{//一定要聲明這個異常16 //之前用try-catch 是用來處理異常,然後後面的代碼繼續執行17 //現在是把出現異常的代碼拋出去,給調用者(這裡的上一級在主函數裡面)18 19 if (b == 0) {20 throw new ArithmeticException();//有可能有這個錯誤的對象,把它拋出去21 }/*else if (arr == null) {//如果上面執行了代碼之後, throw後面的代碼就不會再執行22 throw new NullPointerException();23 } */24 25 System.out.println("啦啦啦");26 int c = a/b;27 //System.out.println(c);//拋出去的話 c 就沒有意義了,就不用列印28 }29 }
自訂異常
需求:類比feiQ(飛秋)上線的時候,發現網線沒有插,這個時候要自己拋出異常(提示程式員網線沒有插);
前提:自訂一個類繼承於Exception
問題:有時候拋出異常必須聲明,有時候拋出異常不需要聲明。
異常體繫結構:在 Exception 後面還分為 運行時異常 和 編譯時間異常;
運行是異常:拋出運行時異常時,是可以不用在方法上聲明異常的,調用者也可以不作處理。
編譯時間異常:拋出編譯時間異常時,就必須在方法方法上聲明異常,調用者也必須要處理一下。
如何區分編譯時間和運行時異常:
那些屬於運行時異常:是RuntimeException 這個異常本身,或者繼承於這個異常的子類都是運行時異常。
除了運行時異常其他的都是編譯時間的異常。Exception 是編譯時間的異常。
1 class NoIPException extends Exception{ 2 3 //自訂沒插網線的異常 4 public NoIPException(String message) { 5 super(message);//如果不寫預設調用父類的空的構造方法 6 } 7 } 8 9 public class star {10 public static void main(String[] args) throws NoIPException{ 11 12 //用feiQ13 String ip = "192.168.10.100";14 15 test(ip);//這裡錯誤,兩個選擇,可以繼續拋,可以處理掉。16 throw new NoIPException("沒插好,網線請插好網線");//這裡再拋出就是去到了java虛擬機器了17 }18 public static void test(String ip) throws NoIPException{19 if (ip == null) {20 throw new NoIPException("沒插好,網線請插好網線");//這裡拋出了給調用者(主函數)21 }22 }23 }
finally 關鍵字
finally 塊 和 try 是一起使用的。
finally:無論出現什麼問題,finally 中的代碼都會執行,除非jvm退出了,代碼才不會被執行。
finally 的作用:finally 非常適合做資源釋放的工作,這樣做就可以保證我這資源檔在任何時候都可以釋放。
1 package study; 2 3 public class star { 4 public static void main(String[] args) { 5 try{ 6 7 test(10,0); 8 9 }catch(Exception e) {10 11 System.out.println("正在處理....");12 }13 }14 public static void test (int a, int b) throws Exception{15 16 int c= 0;17 try18 {19 c = a / b;20 }21 catch (Exception e)22 {23 24 // System.exit(0);//退出jvm25 return; //還是照樣執行finally中的代碼26 }27 finally {28 System.out.println("c = "+c);29 }30 }31 }