–本文摘要–
1、本文的目标讀者:是接觸過Java異常,但是僅限于書本和一些例題,某一天寫着寫着會突然覺得“‘異常’沒什麼意義,Java不是已經幫我們處理了嘛?”的這些朋友。
2、本文的内容摘要:講述日常開發中如何看待‘異常’這個概念,講述在一個中型web項目中,我們如何處理‘異常’。
【版權聲明】歸CSDN賬戶[征途黯然.]/公衆号[三黃工作室]原創,禁止任何網站與個人采集或轉載。
一、本文結構
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiclRnblN2XjlGcjAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHL5VleNl3aU5keRpHW4Z0MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL4kTMzEjNxkTM0ETNwEjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
讀完本文,你一定能解開如下困惑:
1)Java自己會報錯,而且很多網站(比如xx大學的官網)路徑錯誤時,就會報一堆Java錯誤,網站中這些錯誤給使用者的提示,都在報Java原始的錯誤資訊,那還要學異常處理的意義何在?
2)throw和throws有何差別?在方法裡面throw錯誤不是有病嘛?throws在方法名那一行定義到底完成了哪些功能?
3)一個正規項目中,異常多種多樣,開發者是不是要寫很多異常處理?
4)夏天到了,小姐姐們會不會因為沒有男朋友而産生exception,要不要我去處理一下?【哈哈】
二、大學官網讓我覺得‘異常處理毫無意義’
💻言歸正傳。
當年剛學Java的異常,覺得Java真厲害啊,異常先捕獲下來,分分鐘處理掉。結果,一登學校官網,時不時給我報個變量‘xxx’沒有指派。當時我就在想,如果這種基礎錯誤開發者都不做處理,那還要Java中還要‘捕獲’這個概念幹嘛?大家一起用Java自帶的一大串異常報錯不就好了。
三、Java異常
基礎的Java異常關系如下圖3-1所示:
【首先】
Exception
是程式執行時發生的異常,
Error
是JVM運作錯誤(這是緻命錯誤),無法處理。他們共有一個基類是
Throwable
,是以在日常開發中,我們對
Exception
寫的多一點,因為
Error
是緻命錯誤。
異常可以了解為‘程式運作中一個小毛病’。發生
Error
,程式都跑不起來,何來小毛病一說呢。
【其次】
這裡把
RuntimeException
貼出來的目的是,我們項目中用到的異常類型,我們一般都定義為
RuntimeException
類型。用
RuntimeException
的原因,在文章最後有介紹。
四、捕獲與處理
異常,是程式中導緻程式中斷的指令流。如果我們不去管它,那麼發生了異常,程式就會中斷,這是在日常項目中絕對不能發生的(得虧多少錢)。是以,我們要處理它,用一種合适的方式處理,是以用到了try-catch-finally文法。見下圖4-1:
【圖4-1解釋】try-catch-finally文法就像是一個容器,程式執行時,代碼C可能發生異常而導緻程式中斷。我們加一個容器來包含住代碼C,這樣無論它出錯與否,起碼不會讓程式中斷,連個
return
都不能執行。
關于try-catch-finally初學者會産生很多疑問。⭐⭐比較突出的是:既然代碼C出錯了,如果代碼D需要用到代碼C裡面的變量,我繼續執行代碼D有什麼意義呢?
這裡引出我們在開發中使用異常捕獲的目的,見下圖4-2:
【捕獲異常的意義】
首先要保證捕獲内容的原子性(抽象上的原子性),也就是try的内容盡量獨立,不要被try外部引用,否則捕獲是不完整的。
【技術上的意義】
1、捕獲異常,防止方法直接中斷,否則可能連
return
都無法執行。
2、處理可能出錯的變量。如果是該變量異常,我們在try之後,可以給變量設預設值,保證它在接下來可以良好運作。
3、回收空間,保證系統性能。如果一塊空間出錯,我們可以回收,防止性能消耗。
【業務上的意義】
我們在出現異常後,可以設計一個監聽器來識别系統中所有的異常錯誤,對不同類型的異常,傳回不同的資訊給使用者,這樣可以保證使用者看得懂(系統的友好性)。
五、throw與throws
【throw】
throw
是在方法内部抛出一個異常(可以自定義,也可以是Java自帶的異常類)。手動抛出的異常,隻要類型相同,和系統自己産生的異常沒差别,請看以下代碼:
@Test
public void test001(){
int a=2/0;
}
@Test
public void test003(){
throw new ArithmeticException("不可為零");
}
代碼解釋:
int a=2/0;
在Java中會報
ArithmeticException
錯誤,與手動
throw
一個
ArithmeticException
錯誤是等效的。兩個測試函數的報錯大緻相同,見下圖5-1:
關于throw初學者還是會産生很多疑問。⭐⭐大概是:為什麼要在程式中自己抛出異常?不是應該避免程式中的異常嘛?
這個問題的解答請看本文的最後一節。
【throws】
throws
是在方法定義時,添加異常聲明。
throws
可以聲明多個異常類,聲明的基本文法如下代碼:
@Test
public void test001() throws Exception,MyException{
int a=2/0;
}
throws
聲明了本方法中可能出現的異常類。表示如果方法中真的産生了異常,Java程式不會立即中斷,而是會把異常向上傳遞給上一級,讓上一級來處理,而上層的方法必須處理這個異常,不處理會出現Error。
而普通定義的方法,上層方法不是一定要定義try-catch機制。
處理邏輯見下圖5-2:
六、日常開發中的異常處理
⭐【第三節遺留問題】項目開發中,用
RuntimeException
的原因。
【–解答–】
RuntimeException
類型的異常,支援開發者自定義處理,也支援開發者不處理,讓Java來兜底。這樣自由度高,開發簡易,開發中我們大多使用
RuntimeException
類型來派生出自定義異常類型。
⭐【第五節遺留問題】為什麼要在程式中自己抛出異常?不是應該避免程式中的異常嘛?
【–解答–】我們在方法中抛出異常,送出給項目中的異常監聽器來處理異常,分析異常中的類型,然後給使用者傳回對應的提示資訊。
擷取程式設計資源
如果需要擷取程式設計資源,請掃描關注我的公衆号: