偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

教妹學(xué) Java :異常處理機(jī)制

開發(fā) 后端
異常是指中斷程序正常執(zhí)行的一個不確定的事件。當(dāng)異常發(fā)生時,程序的正常執(zhí)行流程就會被打斷。一般情況下,程序都會有很多條語句,如果沒有異常處理機(jī)制,前面的語句一旦出現(xiàn)了異常,后面的語句就沒辦法繼續(xù)執(zhí)行了?!?/div>

[[409061]]

 “二哥,今天就要學(xué)習(xí)異常了嗎?”三妹問。

“是的。只有正確地處理好異常,才能保證程序的可靠性,所以異常的學(xué)習(xí)還是很有必要的。”我說。

“那到底什么是異常呢?”三妹問。

“異常是指中斷程序正常執(zhí)行的一個不確定的事件。當(dāng)異常發(fā)生時,程序的正常執(zhí)行流程就會被打斷。一般情況下,程序都會有很多條語句,如果沒有異常處理機(jī)制,前面的語句一旦出現(xiàn)了異常,后面的語句就沒辦法繼續(xù)執(zhí)行了。”

“有了異常處理機(jī)制后,程序在發(fā)生異常的時候就不會中斷,我們可以對異常進(jìn)行捕獲,然后改變程序執(zhí)行的流程。”

“除此之外,異常處理機(jī)制可以保證我們向用戶提供友好的提示信息,而不是程序原生的異常信息——用戶根本理解不了。”

“不過,站在開發(fā)者的角度,我們更希望看到原生的異常信息,因?yàn)檫@有助于我們更快地找到 bug 的根源,反而被過度包裝的異常信息會干擾我們的視線。”

“Java 語言在一開始就提供了相對完善的異常處理機(jī)制,這種機(jī)制大大降低了編寫可靠程序的門檻,這也是 Java 之所以能夠流行的原因之一。”

“那導(dǎo)致程序拋出異常的原因有哪些呢?”三妹問。

比如說:

  • 程序在試圖打開一個不存在的文件;
  • 程序遇到了網(wǎng)絡(luò)連接問題;
  • 用戶輸入了糟糕的數(shù)據(jù);
  • 程序在處理算術(shù)問題時沒有考慮除數(shù)為 0 的情況;

等等等等。

挑個最簡單的原因來說吧。

  1. public class Demo { 
  2.     public static void main(String[] args) { 
  3.         System.out.println(10/0); 
  4.     } 

這段代碼在運(yùn)行的時候拋出的異常信息如下所示:

  1. Exception in thread "main" java.lang.ArithmeticException: / by zero 
  2.  at com.itwanger.s41.Demo.main(Demo.java:8) 

“你看,三妹,這個原生的異常信息對用戶來說,顯然是不太容易理解的,但對于我們開發(fā)者來說,簡直不要太直白了——很容易就能定位到異常發(fā)生的根源。”

“哦,我知道了。下一個問題,我經(jīng)??吹揭恍┪恼吕锾岬?Exception 和 Error,二哥你能幫我解釋一下它們之間的區(qū)別嗎?”三妹問。

“這是一個好問題呀,三妹!”

從單詞的釋義上來看,error 為錯誤,exception 為異常,錯誤的等級明顯比異常要高一些。

從程序的角度來看,也的確如此。

Error 的出現(xiàn),意味著程序出現(xiàn)了嚴(yán)重的問題,而這些問題不應(yīng)該再交給 Java 的異常處理機(jī)制來處理,程序應(yīng)該直接崩潰掉,比如說 OutOfMemoryError,內(nèi)存溢出了,這就意味著程序在運(yùn)行時申請的內(nèi)存大于系統(tǒng)能夠提供的內(nèi)存,導(dǎo)致出現(xiàn)的錯誤,這種錯誤的出現(xiàn),對于程序來說是致命的。

Exception 的出現(xiàn),意味著程序出現(xiàn)了一些在可控范圍內(nèi)的問題,我們應(yīng)當(dāng)采取措施進(jìn)行挽救。

比如說之前提到的 ArithmeticException,很明顯是因?yàn)槌龜?shù)出現(xiàn)了 0 的情況,我們可以選擇捕獲異常,然后提示用戶不應(yīng)該進(jìn)行除 0 操作,當(dāng)然了,更好的做法是直接對除數(shù)進(jìn)行判斷,如果是 0 就不進(jìn)行除法運(yùn)算,而是告訴用戶換一個非 0 的數(shù)進(jìn)行運(yùn)算。

“三妹,還能想到其他的問題嗎?”

“嗯,不用想,二哥,我已經(jīng)提前做好預(yù)習(xí)工作了。”三妹自信地說,“異常又可以分為 checked 和 unchecked,它們之間又有什么區(qū)別呢?”

“哇,三妹,果然又是一個好問題呢。”

checked 異常(檢查型異常)在源代碼里必須顯式地捕獲或者拋出,否則編譯器會提示你進(jìn)行相應(yīng)的操作;而 unchecked 異常(非檢查型異常)就是所謂的運(yùn)行時異常,通常是可以通過編碼進(jìn)行規(guī)避的,并不需要顯式地捕獲或者拋出。

“我先畫一幅思維導(dǎo)圖給你感受一下。”

首先,Exception 和 Error 都繼承了 Throwable 類。換句話說,只有 Throwable 類(或者子類)的對象才能使用 throw 關(guān)鍵字拋出,或者作為 catch 的參數(shù)類型。

面試中經(jīng)常問到的一個問題是,NoClassDefFoundError 和 ClassNotFoundException 有什么區(qū)別?

“三妹你知道嗎?”

“不知道,二哥,你解釋下唄。”

它們都是由于系統(tǒng)運(yùn)行時找不到要加載的類導(dǎo)致的,但是觸發(fā)的原因不一樣。

  • NoClassDefFoundError:程序在編譯時可以找到所依賴的類,但是在運(yùn)行時找不到指定的類文件,導(dǎo)致拋出該錯誤;原因可能是 jar 包缺失或者調(diào)用了初始化失敗的類。
  • ClassNotFoundException:當(dāng)動態(tài)加載 Class 對象的時候找不到對應(yīng)的類時拋出該異常;原因可能是要加載的類不存在或者類名寫錯了。

其次,像 IOException、ClassNotFoundException、SQLException 都屬于 checked 異常;像 RuntimeException 以及子類 ArithmeticException、ClassCastException、ArrayIndexOutOfBoundsException、NullPointerException,都屬于 unchecked 異常。

unchecked 異??梢圆辉诔绦蛑酗@示處理,就像之前提到的 ArithmeticException 就是的;但 checked 異常必須顯式處理。

比如說下面這行代碼:

  1. Class clz = Class.forName("com.itwanger.s41.Demo1"); 

如果沒做處理,比如說在 Intellij IDEA 環(huán)境下,就會提示你這行代碼可能會拋出 java.lang.ClassNotFoundException。

建議你要么使用 try-catch 進(jìn)行捕獲:

  1. try { 
  2.     Class clz = Class.forName("com.itwanger.s41.Demo1"); 
  3. } catch (ClassNotFoundException e) { 
  4.     e.printStackTrace(); 

注意打印異常堆棧信息的 printStackTrace() 方法,該方法會將異常的堆棧信息打印到標(biāo)準(zhǔn)的控制臺下,如果是測試環(huán)境,這樣的寫法還 OK,如果是生產(chǎn)環(huán)境,這樣的寫法是不可取的,必須使用日志框架把異常的堆棧信息輸出到日志系統(tǒng)中,否則可能沒辦法跟蹤。

要么在方法簽名上使用 throws 關(guān)鍵字拋出:

  1. public class Demo1 { 
  2.     public static void main(String[] args) throws ClassNotFoundException { 
  3.         Class clz = Class.forName("com.itwanger.s41.Demo1"); 
  4.     } 

這樣做的好處是不需要對異常進(jìn)行捕獲處理,只需要交給 Java 虛擬機(jī)來處理即可;壞處就是沒法針對這種情況做相應(yīng)的處理。

“二哥,針對 checked 異常,我在知乎上看到一個帖子,說 Java 中的 checked 很沒有必要,這種異常在編譯期要么 try-catch,要么 throws,但又不一定會出現(xiàn)異常,你覺得這樣的設(shè)計(jì)有意義嗎?”三妹提出了一個很尖銳的問題。

“哇,這種問題問的好。”我不由得對三妹心生敬佩。

“的確,checked 異常在業(yè)界是有爭論的,它假設(shè)我們捕獲了異常,并且針對這種情況作了相應(yīng)的處理,但有些時候,根本就沒法處理。”我說,“就拿上面提到的 ClassNotFoundException 異常來說,我們假設(shè)對其進(jìn)行了 try-catch,可真的出現(xiàn)了 ClassNotFoundException 異常后,我們也沒多少的可操作性,再 Class.forName() 一次?”

另外,checked 異常也不兼容函數(shù)式編程,后面如果你寫 Lambda/Stream 代碼的時候,就會體驗(yàn)到這種苦澀。

當(dāng)然了,checked 異常并不是一無是處,尤其是在遇到 IO 或者網(wǎng)絡(luò)異常的時候,比如說進(jìn)行 Socket 鏈接,我大致寫了一段:

  1. public class Demo2 { 
  2.     private String mHost; 
  3.     private int mPort; 
  4.     private Socket mSocket; 
  5.     private final Object mLock = new Object(); 
  6.  
  7.     public void run() { 
  8.     } 
  9.  
  10.     private void initSocket() { 
  11.         while (true) { 
  12.             try { 
  13.                 Socket socket = new Socket(mHost, mPort); 
  14.                 synchronized (mLock) { 
  15.                     mSocket = socket; 
  16.                 } 
  17.                 break; 
  18.             } catch (IOException e) { 
  19.                 e.printStackTrace(); 
  20.             } 
  21.         } 
  22.     } 

當(dāng)發(fā)生 IOException 的時候,socket 就重新嘗試連接,否則就 break 跳出循環(huán)。意味著如果 IOException 不是 checked 異常,這種寫法就略顯突兀,因?yàn)?IOException 沒辦法像 ArithmeticException 那樣用一個 if 語句判斷除數(shù)是否為 0 去規(guī)避。

或者說,強(qiáng)制性的 checked 異??梢宰屛覀冊诰幊痰臅r候去思考,遇到這種異常的時候該怎么更優(yōu)雅的去處理。顯然,Socket 編程中,肯定是會遇到 IOException 的,假如 IOException 是非檢查型異常,就意味著開發(fā)者也可以不考慮,直接跳過,交給 Java 虛擬機(jī)來處理,但我覺得這樣做肯定更不合適。

“好了,三妹,關(guān)于異常處理機(jī)制這節(jié)就先講到這里吧。”我松了一口氣,對三妹說。

“好的,二哥,你去休息吧。”

“對了,三妹,我定個姑婆婆的外賣吧,晚上我們喝粥。”

“好呀,我要兩個豆沙包。”

本文轉(zhuǎn)載自微信公眾號「沉默王二」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系沉默王二公眾號。

 

責(zé)任編輯:武曉燕 來源: 沉默王二
相關(guān)推薦

2021-07-26 17:22:02

Java

2011-03-17 09:20:05

異常處理機(jī)制

2021-06-06 20:56:48

Java內(nèi)存 intern

2011-07-21 15:20:41

java異常處理機(jī)制

2021-05-10 11:38:07

Java數(shù)組IDEA

2020-10-26 09:36:45

Java變量數(shù)據(jù)

2020-11-18 09:44:49

Java命名約定

2011-04-06 10:27:46

Java異常處理

2021-07-08 22:43:41

ThrowThrowsJava

2021-06-11 18:08:00

Java字符串拼接

2010-03-05 15:40:16

Python異常

2024-03-04 10:00:35

數(shù)據(jù)庫處理機(jī)制

2009-08-05 18:09:17

C#異常處理機(jī)制

2020-10-29 10:28:31

Java數(shù)據(jù)類型

2021-03-02 09:12:25

Java異常機(jī)制

2023-03-08 08:54:59

SpringMVCJava

2023-06-15 14:09:00

解析器Servlet容器

2015-12-28 11:25:51

C++異常處理機(jī)制

2023-02-23 08:15:33

Spring異常處理機(jī)制

2011-07-01 14:20:59

Qt 事件
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號