认识异常真的很简单
1. Throwable:是異常體系的頂層類,其派生出兩個重要的子類, Error 和 Exception
2. Error:指的是Java虛擬機無法解決的嚴重問題,比如:JVM的內部錯誤、資源耗盡等,典型代表: StackOverflflowError和OutOfMemoryError,一旦發生回力乏術。
3. Exception:異常產生后程序員可以通過代碼進行處理,使程序繼續執行。比如:感冒、發燒。我們平時所說的異常就是Exception。其中上面紅色框是編譯時異常,也叫受查異常;藍色框里面的是運行時異常。
異常的分類
編譯時異常 在程序編譯期間發生的異常,稱為編譯時異常,也稱為受檢查異常;例如:java: 未報告的異常錯誤java.lang.CloneNotSupportedException; 必須對其進行捕獲或聲明以便拋出?
運行時異常
在程序執行期間發生的異常,稱為運行時異常,也稱為非受檢查異常(Unchecked Exception) RunTimeException以及其子類對應的異常,都稱為運行時異常。比如:NullPointerException、 ArrayIndexOutOfBoundsException、ArithmeticException。異常處理
EAFP方法
try { 登陸游戲(); 開始匹配(); 游戲確認(); 選擇英雄(); 載入游戲畫面(); ... } catch (登陸游戲異常) {處理登陸游戲異常; } catch (開始匹配異常) { 處理開始匹配異常; } catch(游戲確認異常) {處理游戲確認異常;} catch (選擇英雄異常) { 處理選擇英雄異常; } catch (載入游戲畫面異常) {處理載入游戲畫面異常; } 在Java中,異常處理主要的5個關鍵字:throw、try、catch、fifinal、throws。異常的拋出
在Java中,可以借助throw關鍵字,拋出一個指定的異常對象,將錯誤信息告知給調用者。具體語法如下: throw new XXXException("異常產生的原因"); public static int getElement(int[]array,int index){if(array==null){throw new NullPointerException();}if(index<0||index>=array.length){throw new ArrayIndexOutOfBoundsException();}return array[index];}public static void main(String[] args) {int[]array=new int[]{1,2,3};int ret=getElement(array,3);System.out.println(ret);}如果array=null則輸出NullPointerException,如果index<0或者大于等于2則輸出ArrayIndexOutOfBoundsException。
【注意事項】 1. throw必須寫在方法體內部 2. 拋出的對象必須是Exception 或者 Exception 的子類對象 3. 如果拋出的是 RunTimeException 或者 RunTimeException 的子類,則可以不用處理,直接交給JVM來處理 4. 如果拋出的是編譯時異常,用戶必須處理,否則無法通過編譯 5. 異常一旦拋出,其后的代碼就不會執行 6.可以捕獲多個異常,但是不是同時,因為不可能同時拋多個異常。異常的捕獲
異常的捕獲,也就是異常的具體處理方式,主要有兩種:異常聲明throws 以及 try-catch捕獲處理。異常聲明throws:
語法格式: 修飾符 返回值類型 方法名(參數列表) throws 異常類型1,異常類型2...{ } 當方法中拋出編譯時異常,用戶不想處理該異常,此時就可以借助throws將異常拋 給方法的調用者來處理。即當前方法不處理異常,提醒方法的調用者處理異常。 例如:我們上面的clone()方法 public class Person {private String name;private int age;public Person clone() throws CloneNotSupportedException {return (Person) super.clone();} }try-catch捕獲并處理
throws對異常并沒有真正處理,而是將異常報告給拋出異常方法的調用者,由調用者處理。如果真正要對異常進行處理,就需要try-catch。 語法格式: try{ // 將可能出現異常的代碼放在這里 }catch(要捕獲的異常類型 e){ // 如果try中的代碼拋出異常了,此處catch捕獲時異常類型與try中拋出的異常類型一致時,或者是try中拋出異常的基類 時,就會被捕獲到 // 對異常就可以正常處理,處理完成后,跳出try-catch結構,繼續執行后序代碼 }[catch(異常類型 e){ // 對異常進行處理 }fifinally{ // 此處代碼一定會被執行到 } // 后序代碼 // 當異常被捕獲到時,異常就被處理了,這里的后序代碼一定會執行 // 如果捕獲了,由于捕獲時類型不對,那就沒有捕獲到,這里的代碼就不會被執行 我們寫一個需求:克隆person,如果無法克隆,拋出異常,調用者進行異常處理 public static void main(String[] args) {try {Person person1 = new Person();Person person2 = person1.clone();System.out.println("try塊內的代碼不會被執行");} catch (CloneNotSupportedException e) {e.printStackTrace();//哪一行出錯System.out.println("處理異常");}System.out.println("其他代碼");}我們發現異常被捕獲后處理,其他代碼也可以正常運行。
【注意事項】 1. try塊內拋出異常位置之后的代碼將不會被執行 2. 如果拋出異常類型與catch時異常類型不匹配,即異常不會被成功捕獲,也就不會被處理,繼續往外拋,直到JVM收到后中斷程序----異常是按照類型來捕獲的 3. try中可能會拋出多個不同的異常對象,則必須用多個catch來捕獲----即多種異常,多次捕獲4.如果異常之間具有父子關系,一定是子類異常在前catch,父類異常在后catch,否則語法錯誤
finally?
在寫程序時,有些特定的代碼,不論程序是否發生異常,都需要執行,比如程序中打開的資源:網絡連接、數據庫連接、IO流等,在程序正?;蛘弋惓M顺鰰r,必須要對資源進進行回收。另外,因為異常會引發程序的跳轉,可能導致有些語句執行不到,fifinally就是用來解決這個問題的。 public static void main(String[] args) {Scanner scanner=new Scanner(System.in);try{int[]array=null;System.out.println(array.length);}catch (ArithmeticException e){e.printStackTrace();System.out.println("捕獲到一個算數異常");}catch (NullPointerException e){e.printStackTrace();System.out.println("空指針異常");}finally {scanner.close();System.out.println("資源回收");}System.out.println("其他代碼");} }不管程序是否拋出異常,finally都會被執行。
問題:下面代碼返回10還是19
public static int function(int a){try{if(a==0){throw new ArithmeticException();}return a;}catch (ArithmeticException e){System.out.println("算數異常");}finally {return 19;}}public static void main(String[] args) {int a=10;System.out.println(function(a));}答案:19
所以finally一定會被執行,因此避免在finally里面return,這不是一個好習慣。
【異常處理流程總結】 1.程序先執行 try 中的代碼 2.如果 try 中的代碼出現異常, 就會結束 try 中的代碼, 看和 catch 中的異常類型是否匹配. 3.如果找到匹配的異常類型, 就會執行 catch 中的代碼 4.如果沒有找到匹配的異常類型, 就會將異常向上傳遞到上層調用者. 5.無論是否找到匹配的異常類型, fifinally 中的代碼都會被執行到(在該方法結束之前執行). 6.如果上層調用者也沒有處理的了異常, 就繼續向上傳遞. 7.一直到 main 方法也沒有合適的代碼處理異常, 就會交給 JVM 來進行處理, 此時程序就會異常終止自定義異常
自定義異常通常會繼承自 Exception 或者 RuntimeException 繼承自 Exception 的異常默認是受查異常 繼承自 RuntimeException 的異常默認是非受查異常 class UserNameException extends RuntimeException{//自定義一個異常public UserNameException(String message) {super(message);} } class PasswordException extends RuntimeException{//自定義一個異常public PasswordException(String message) {super(message);} } public class Login {private static String name="yyds";private static String password="12345";public static void loginInfo(String Name,String Password){if(!name.equals(Name)){throw new UserNameException("用戶名異常"+Name);}if(!password.equals(Password)){throw new PasswordException("密碼錯誤"+Password);}System.out.println("登入成功");}public static void main(String[] args) {try{loginInfo("yysd","12345");}catch (UserNameException e){e.printStackTrace();}catch (PasswordException e){e.printStackTrace();}} }總結
- 上一篇: 考研数学之线性代数知识点
- 下一篇: 线性代数学习笔记——行列式(针对期末与考