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 空指針異常 9 test(4, 0,arr);//java.lang.ArithmeticException: / by zero 10 } 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的時候就經常用到(知識點後期補上);
為什麼不直接用最大的異常:
為了讓我們跟精確快速地找到錯誤的根源。如:空指針異常,用最大的異常的話,就看不出來是空指針異常。
方式二:拋出異常
拋出異常處理關鍵的兩個關鍵字(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 //用feiQ 13 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 try 18 { 19 c = a / b; 20 } 21 catch (Exception e) 22 { 23 24 // System.exit(0);//退出jvm 25 return; //還是照樣執行finally中的代碼 26 } 27 finally { 28 System.out.println("c = "+c); 29 } 30 } 31 }