Java匹馬行天下之JavaSE核心技術——異常處理
- 2020 年 4 月 21 日
- 筆記
- 【1.Java匹馬行天下】
Java匹馬行天下之JavaSE核心技術——異常處理
異常的簡介
在Java中,異常就是Java在編譯、運行或運行過程中出現的錯誤。
程序錯誤分為三種:編譯錯誤、運行時錯誤和邏輯錯誤
- 編譯錯誤是因為程序沒有遵循語法規則,編譯程序能夠自己發現並且提示我們錯誤的原因和位置,這個也是新手在剛接觸編程語言時經常遇到的問題。
- 運行時錯誤是因為程序在執行時,運行環境發現了不能執行的操作。
- 邏輯錯誤是因為程序沒有按照預期的邏輯順序執行。異常也就是指程序運行時發生錯誤,而異常處理就是對這些錯誤進行處理和控制。
下面看一段代碼:
package com.yichang; public class Test { public static void main(String[] args) { System.out.println(1/0);//0不能做除數 } }
運行後的結果為:
我們發現程序出了錯,而圖中的錯誤信息告訴我們兩個信息:
- 出了什麼錯
- 出錯的位置
異常產生的過程
以上面的代碼為例,程序在運行過程中,先運行main方法,然後執行到1/0時,程序就會報錯,程序先會創建一個錯誤對象,然後把這個錯誤對象丟出來,我們都知道我們的程序是運行在Java虛擬機(JVM)上,程序丟出來的錯誤對象就會被JVM捕獲到。當然,JVM捕獲到錯誤對象後,它也不知道該怎麼辦,它不可能幫你調錯,JVM會把錯誤信息給你打印出來。
總結一下,就是:
- 上例中出現的異常是運行時異常(異常是錯誤)
- 程序會創建一個錯誤對象,然後把錯誤對象丟出來(拋異常)
- 默認由JVM把錯誤信息進行捕獲,打印出來(捕獲異常)
為什麼不能直接讓JVM獲取異常
先看下面代碼:
package com.yichang; public class Test { public static void main(String[] args) { System.out.println(1/0);//0不能做除數 System.out.println("你好"); } }
運行結果為:
從上面代碼和運行結果中,我們不難看出在控制台沒有打印出你好。出現這種情況,是因為在JVM捕獲到異常後,程序會終止。換句話說,在由JVM來處理錯誤的時候,此時,程序會終止,因此異常之後的代碼就無法運行了。我們可以根據生活實例想想,什麼時候百度會因為搜不到東西停服務,肯定是不會的,因此我們後面要做的就是如何在異常到達JVM之前把異常攔下來,自己單獨處理,就不要麻煩JVM了。
異常的分類
在上面實例中我說過程序會創建錯誤對象,說到對象,我們都知道對象是由類創建的,那異常對象肯定是通過異常類來創建的。下面圖中就是Java給我們提供的異常類:
下面我來說一下異常的分類:
- RuntimeException:運行時異常,一般不手動處理,出問題了再處理。
- 其他Exception:必須要經過手動處理。
- Error:一般指的是系統級錯誤。
我再用生活例子解釋一下這三種異常,便於新手理解: 假設我們現在開車上山,
- 開車的過程中發現山上有許多小石頭,但我們不可能把所有小石頭都處理了,這時候我們依舊正常開,什麼時候小石頭把車胎給弄壞了,我們再下來,換備胎,這就是運行時異常
- 開車的過程中發現前面有一個很大的石頭擋住了路,這時候你必須下車先把這石頭挪走,你才能繼續上山,這也就是其他Exception。
- 開車上山的過程中山塌陷了,你又無法處理,必須要等到山好了你才能繼續出發,也就是Error,就是這種錯誤我們一般的程序員是處理不了的。
異常的處理方法
try···catch處理
語法:
try{ //嘗試執行的代碼 }catch(Exception e){ //處理異常的代碼 }finally{ //最終的 }
下面我將文中案例進行改造:
package com.yichang; public class Test { public static void main(String[] args) { try { System.out.println(1/0);//0不能做除數 }catch (Exception e){ e.printStackTrace();//打印錯誤信息,給程序員看的 System.out.println("系統出現錯誤,請聯繫管理員");//給客戶看的 }finally { //一般做收尾工作 System.out.println("你好"); } } }
運行結果為:
- try— 用於監聽。將要被監聽的代碼(可能拋出異常的代碼)放在try語句塊之內,當try語句塊內發生異常時,異常就被拋出。
- catch— 用於捕獲異常。catch用來捕獲try語句塊中發生的異常。
- finally— finally語句塊總是會被執行。它主要用於回收在try塊里打開的物力資源(如數據庫連接、網絡連接和磁盤文件)。
throws和throw處理
- throws表示方法準備要扔出來一個異常
- throw表示向外拋出異常
舉例說明:
package com.yichang; public class Test1 { public static void chu(int a,int b) throws Exception{ if (b==0){ throw new Exception("除數不能為0"); }else { System.out.println(a/b); } } public static void main(String[] args) throws Exception{ chu(1,0); } }
運行結果:
以上這兩種方法都是處理異常的,如果這個異常你可以處理,就用try···catch方法捕獲並處理異常,如果這個異常你不能處理,就用throws方法拋出異常,但作為程序員的我們要始終記住一句話:產生的錯誤儘可能的自己處理,少向外拋出異常。
自定義異常
到這可能有的朋友要問了,為什麼要自定義異常,Java給的那麼多還不夠用嗎?我可以告訴你,當然不夠用,比如在生活中,我們都知道外面的澡堂子裡邊是分男女澡堂的,如果有男顧客走進了女澡堂或有女顧客走進了男澡堂,就壞事了,這算是一個大異常吧,那大家想,jdk會給我們提供跟性別還有澡堂子有關的異常嗎?肯定是不可能的,那此時就需要我們自定義異常。我以澡堂子為例,寫一個程序,供大家參考。
自定義異常:直接繼承Exception或者RuntimeException來是實現自定義異常
Person類
package com.yichang; public class Person { String name;//姓名 String gender;//性別 public Person(String name, String gender) { this.name = name; this.gender = gender; } }
ZaoTangZi類
package com.yichang; public class ZaoTangZi { public void man(Person p) throws GenderException{ if (p.gender=="男"){ System.out.println("歡迎光臨"); }else { //需要拋出一個異常 throw new GenderException("性別錯誤,這裡是男澡堂子"); } } }
GenderException類
package com.yichang; public class GenderException extends Exception{ //自己定義的異常必須要繼承Exception或RuntimeException public GenderException(String msg){ super(msg);//調用父類的構造方法,Exception(msg) } }
Test類
package com.yichang; public class Test { public static void main(String[] args) throws GenderException{ Person p1 = new Person("張三","男"); Person p2 = new Person("小花","女"); ZaoTangZi z = new ZaoTangZi(); z.man(p2); } }
運行結果:
總結
寫到這,這篇異常處理的文章就寫完了,看完後我們應該明白以下幾個問題:
- 什麼是異常
- 出現異常如何處理
- 如何自定義異常
可能寫的有點啰嗦了,但對新手是友好的,還請大家多多包涵,希望能對大家有所幫助。