java的異常Exception

1.什麼是異常

非正常的,不同於平常的.

       生活中:醫生說,你的身體某個部位有異常,該部位和正常相比有點不同,該部位的功能將受影響.張三要開車去上班,正常情況下,應該是到達公司,上班.不正常的情況下,車子壞了,只能走路去,導致上班遲到.
       程序中:在程序中,代碼出現錯誤,程序就會終止運行.
異常指的並不是語法錯誤,語法錯了,編譯不通過,不會產生字節碼文件,根本不能運行.
----------------------------------------
異常處理是衡量一門語言是否成熟的標準之一,主流的語言Java,C++,C#等支持異常處理機制.
異常處理機制可以讓程序有更好的容錯性,使我們的代碼更健壯.
遺憾的是傳統的C語言卻沒有異常,此時只能程序員通常使用方法的特定返回值來表示異常情況,並且使用if語句來判斷正常和非正常情況,那沒有異常會帶來什麼問題呢?

----------------------------------------
沒有異常機制存在的缺點:
1:使用方法的返回值來表示異常情況有限,無法窮舉所有的異常情況.
2:異常流程代碼和正常流程代碼混合一起,增大了程序的複雜性,可讀性也不好.

3:隨着系統規模的不斷擴大,程序的可維護性極低.

2.java的異常體系



1):Error:表示錯誤,一般指JVM相關的不可修復的錯誤,如,系統崩潰,內存溢出,JVM錯誤等,由JVM拋出,我們不需要處理.
           幾乎所有的子類都是以Error作爲類名的後綴.
2):Exception:表示異常,指程序中出現不正常的情況,該問題可以修復(處理異常).
          幾乎所有的子類都是以Exception作爲類名的後綴.
----------------------------------------------------------------------------------------------------
出現異常,不要緊張,把異常的簡單類名,拷貝到API中去查.
----------------------------------------------------------------------------------------------------
常見的Error:
    StackOverflowError:當應用程序遞歸太深而發生內存溢出時,拋出該錯誤。 
常見的Exception:
    NullPointerException
:空指針異常,一般指當對象爲null的時候,調用了該對象的方法,字段.
    ArrayIndexOutOfBoundsException:數組的索引越界,(小於0或者大於等於數組長度)
    NumberFormatException:數字格式化異常, 一般指,把非0~9的字符串轉換爲整數.
--------------------------------------------------------------
證明出現異常之後,程序會中斷,所以必須處理異常.

2.捕獲異常

如果異常出現的話,會立刻終止程序,所以我們得處理異常:
     1):該方法不處理,而是聲明拋出,由該方法的調用者來處理(throws).
     2):在方法中使用try-catch的語句塊來處理異常.
-----------------------------------------------------------------------
使用try-catch捕獲單個異常,語法如下:
try{
     編寫可能會出現異常的代碼
}catch(異常類型  e){
     處理異常的代碼
     //記錄日誌/打印異常信息/繼續拋出異常

}

注意:try和catch都不能單獨使用,必須連用.

舉例:
1)正常情況
[java]  view plain  copy
  1. public class ExceptionDemo1 {  
  2.   
  3.     public static void main(String[] args) {  
  4.         System.out.println("begin----");  
  5.         int ret = 10/2;  //正常的結果  
  6.         System.out.println("結果="+ret);  
  7.         System.out.println("end------");  
  8.     }  
  9. }  
2)出現異常,程序會中斷執行
[java]  view plain  copy
  1. public class ExceptionDemo1 {  
  2.   
  3.     public static void main(String[] args) {  
  4.         System.out.println("begin----");  
  5.         int ret = 10/0;  //除數爲0,出現異常  
  6.         System.out.println("結果="+ret);  
  7.         System.out.println("end------");  
  8.     }  
  9. }  

可以看出程序出現異常後,程序會終止,這時我們需要處理異常
[java]  view plain  copy
  1. public class ExceptionDemo1 {  
  2.   
  3.     public static void main(String[] args) {  
  4.         System.out.println("begin----");  
  5.         try{          
  6.             int ret = 10/0;  //除數爲0,出現異常  
  7.             System.out.println("結果="+ret);  
  8.         }catch(ArithmeticException e){  
  9.             System.out.println("出異常啦!!!!");  
  10.         }  
  11.         System.out.println("end------");  
  12.     }  
  13. }  


分析:

可以看出異常出現後程序跳轉到catch塊兒執行,當catch塊兒的代碼執行完之後,程序並沒有停止,而是繼續執行後面的代碼

3.獲取異常信息

如何獲取異常信息,Throwable類的方法:
1):String getMessage():獲取異常的描述信息,原因(提示給用戶的時候,就提示錯誤原因).
2):String toString():獲取異常的類型和異常描述信息(不用).
3):void printStackTrace():打印異常的跟蹤棧信息並輸出到控制檯.  不需要使用System.out.println.
    包含了異常的類型,異常的原因,還包括異常出現的位置,在開發和調試階段,都得使用printStackTrace.
    記住:現在在catch語句塊中,必須寫:e.printStackTrace();目的:查看異常的具體信息,方便調試和修改.

[java]  view plain  copy
  1. public class ExceptionDemo1 {  
  2.   
  3.     public static void main(String[] args) {  
  4.         System.out.println("begin----");  
  5.         try{          
  6.             int ret = 10/0;  //除數爲0,出現異常  
  7.             System.out.println("結果="+ret);  
  8.         }catch(ArithmeticException e){  
  9.             System.out.println("異常信息"+e.toString());   //異常信息java.lang.ArithmeticException: / by zero  
  10.             System.out.println("異常信息"+e.getMessage());  //異常信息/ by zero  
  11.             //推薦使用下面這個  
  12.             e.printStackTrace();//自帶打印功能異常信息,java.lang.ArithmeticException: / by zero  
  13.                                                 //at cn.anyglobe.ExceptionDemo1.main(ExceptionDemo1.java:8)  
  14.         }  
  15.         System.out.println("end------");  
  16.     }  
  17. }  

使用try-catch捕獲多個異常:

try{
     編寫可能會出現異常的代碼
}catch(異常類型A  e){  當try中出現A類型異常,就用該catch來捕獲.
     處理異常的代碼
     //記錄日誌/打印異常信息/繼續拋出異常

}catch(異常類型B  e){  當try中出現B類型異常,就用該catch來捕獲.
     處理異常的代碼
     //記錄日誌/打印異常信息/繼續拋出異常

}

[java]  view plain  copy
  1. public class ExceptionDemo1 {  
  2.   
  3.     public static void main(String[] args) {  
  4.         System.out.println("begin----");  
  5.         String sNum1 = "10"//輸入的除數  
  6.         String sNum2 = "0"//輸入的被除數  
  7.         try{      
  8.             int num1 = Integer.parseInt(sNum1);  
  9.             int num2 = Integer.parseInt(sNum2);  
  10.             int ret = num1/num2;  //除數爲0,出現異常  
  11.             System.out.println("結果="+ret);  
  12.         }catch(ArithmeticException e){  
  13.             System.out.println("除數爲0");  
  14.         }catch (NumberFormatException e) {  
  15.             System.out.println("類型轉換異常");  
  16.         }  
  17.         System.out.println("end------");  
  18.     }  
  19. }  


[java]  view plain  copy
  1. public class ExceptionDemo1 {  
  2.   
  3.     public static void main(String[] args) {  
  4.         System.out.println("begin----");  
  5.         String sNum1 = "10"//輸入的除數  
  6.         String sNum2 = "0"//輸入的被除數  
  7.         try{      
  8.             int num1 = Integer.parseInt(sNum1);  
  9.             int num2 = Integer.parseInt(sNum2);  
  10.             int ret = num1/num2;  //除數爲0,出現異常  
  11.             System.out.println("結果="+ret);  
  12.         }catch(ArithmeticException e){  
  13.             System.out.println("除數爲0");  
  14.         }catch (NumberFormatException e) {  
  15.             System.out.println("類型轉換異常");  
  16.         }  
  17.         System.out.println("end------");  
  18.     }  
  19. }  

從上面兩個代碼可以看出,捕獲多個異常時,程序只需要一個catch捕獲,不可能同時出現多個異常.

如果不知道什麼異常的話可以用父類接收
[java]  view plain  copy
  1. public class ExceptionDemo1 {  
  2.   
  3.     public static void main(String[] args) {  
  4.         System.out.println("begin----");  
  5.         String sNum1 = "10"//輸入的除數  
  6.         String sNum2 = "0"//輸入的被除數  
  7.         try {  
  8.             //String轉換爲int類型  
  9.             int num1 = Integer.parseInt(sNum1);  
  10.             int num2 = Integer.parseInt(sNum2);  
  11.             //兩個整數相除  
  12.             int ret = num1 / num2; //除數爲0,出現異常  
  13.             System.out.println("結果=" + ret);  
  14.         } catch (ArithmeticException e) {  
  15.             System.out.println("除數爲0");  
  16.         } catch (NumberFormatException e) {  
  17.             System.out.println("類型轉換異常");  
  18.         } catch (Exception e) {  
  19.             e.printStackTrace(); //其他異常統一用父類接受也可以  
  20.         }  
  21.         System.out.println("end------");  
  22.     }  
  23. }  
或者直接用父類接收全部異常
[java]  view plain  copy
  1. public class ExceptionDemo1 {  
  2.   
  3.     public static void main(String[] args) {  
  4.         System.out.println("begin----");  
  5.         String sNum1 = "10"//輸入的除數  
  6.         String sNum2 = "0"//輸入的被除數  
  7.         try {  
  8.             //String轉換爲int類型  
  9.             int num1 = Integer.parseInt(sNum1);  
  10.             int num2 = Integer.parseInt(sNum2);  
  11.             //兩個整數相除  
  12.             int ret = num1 / num2; //除數爲0,出現異常  
  13.             System.out.println("結果=" + ret);  
  14.         } catch (Exception e) {  
  15.             e.printStackTrace(); //直接用異常父類接收  
  16.         }  
  17.         System.out.println("end------");  
  18.     }  
  19. }  
注意:
1:一個catch語句,只能捕獲一種類型的異常,如果需要捕獲多種異常,就得使用多個catch語句.
2:代碼在一瞬間只能出現一種類型的異常,只需要一個catch捕獲,不可能同時出現多個異常.

4.finally代碼塊

finally語句塊表示最終都會執行的代碼,無論有沒有異常.
---------------------------------------------------------------------------------------
什麼時候的代碼必須最終執行:
當我們在try語句塊中打開了一些物理資源(磁盤文件/網絡連接/數據庫連接等),我們都得在使用完之後,最終關閉打開的資源.
---------------------------------------------------------------------------------------
finally的兩種語法:
  1):try...finally: 此時沒有catch來捕獲異常,因爲此時根據應用場景,我們會拋出異常,自己不處理.
  2):try...catch....finally:自身需要處理異常,最終還得關閉資源.

沒有異常:
[java]  view plain  copy
  1. public class ExceptionDemo2 {  
  2.   
  3.     public static void main(String[] args) {  
  4.         System.out.println("begin....");  
  5.         try {  
  6.             int ret = 10 / 2;  
  7.         } catch (ArithmeticException e) {  
  8.             System.out.println("異常:除數爲0");  
  9.         } finally {  
  10.             System.out.println("關閉資源");  
  11.         }  
  12.         System.out.println("end.....");  
  13.     }  
  14. }  


出現異常:
[java]  view plain  copy
  1. public class ExceptionDemo2 {  
  2.   
  3.     public static void main(String[] args) {  
  4.         System.out.println("begin....");  
  5.         try {  
  6.             int ret = 10 / 0;  
  7.         } catch (ArithmeticException e) {  
  8.             System.out.println("異常:除數爲0");  
  9.         } finally {  
  10.             System.out.println("關閉資源");  
  11.         }  
  12.         System.out.println("end.....");  
  13.     }  
  14. }  


可以看見,沒有異常或者出現異常之後,程序會處理異常,打印異常信息,然後會進入finally代碼塊執行代碼塊中的內容,無論有沒有異常,finally中的代碼都會執行.
注意:finally不能單獨使用.
---------------------------------------------------------------------------------------
當只有在try或者catch中調用退出JVM的相關方法,此時finally纔不會執行,否則finally永遠會執行.
System.exit(0);//退出JVM
[java]  view plain  copy
  1. public  public class ExceptionDemo2 {  
  2.   
  3.     public static void main(String[] args) {  
  4.         System.out.println("begin....");  
  5.         try {  
  6.             int ret = 10 / 0;  
  7.         } catch (ArithmeticException e) {  
  8.             System.out.println("異常:除數爲0");  
  9.             System.exit(0);//JVM退出  
  10.         } finally {  
  11.             System.out.println("關閉資源"); //此時不執行  
  12.         }  
相關文章
相關標籤/搜索