日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢(xún)客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

作者:allen4tech 慕課網(wǎng)

JAVA 異常類(lèi)型結(jié)構(gòu)

Throwable 是所有異常類(lèi)型的基類(lèi),Throwable 下一層分為兩個(gè)分支,Error 和 Exception.

這應(yīng)該是全網(wǎng)講解JAVA 異常處理最全的文章了

 

Error 和 Exeption

  • Error

Error 描述了 JAVA 程序運(yùn)行時(shí)系統(tǒng)的內(nèi)部錯(cuò)誤,通常比較嚴(yán)重,除了通知用戶(hù)和盡力使應(yīng)用程序安全地終止之外,無(wú)能為力,應(yīng)用程序不應(yīng)該嘗試去捕獲這種異常。通常為一些虛擬機(jī)異常,如 StackOverflowError 等。

  • Exception

Exception 類(lèi)型下面又分為兩個(gè)分支,一個(gè)分支派生自 RuntimeException,這種異常通常為程序錯(cuò)誤導(dǎo)致的異常;另一個(gè)分支為非派生自 RuntimeException 的異常,這種異常通常是程序本身沒(méi)有問(wèn)題,由于像 I/O 錯(cuò)誤等問(wèn)題導(dǎo)致的異常,每個(gè)異常類(lèi)用逗號(hào)隔開(kāi)。

受查異常和非受查異常

  • 受查異常

受查異常會(huì)在編譯時(shí)被檢測(cè)。如果一個(gè)方法中的代碼會(huì)拋出受查異常,則該方法必須包含異常處理,即 try-catch 代碼塊,或在方法簽名中用 throws 關(guān)鍵字聲明該方法可能會(huì)拋出的受查異常,否則編譯無(wú)法通過(guò)。如果一個(gè)方法可能拋出多個(gè)受查異常類(lèi)型,就必須在方法的簽名處列出所有的異常類(lèi)。

通過(guò) throws 關(guān)鍵字聲明可能拋出的異常

這應(yīng)該是全網(wǎng)講解JAVA 異常處理最全的文章了

 

try-catch 處理異常

這應(yīng)該是全網(wǎng)講解JAVA 異常處理最全的文章了

 

  • 非受查異常

 

非受查異常不會(huì)在編譯時(shí)被檢測(cè)。JAVA 中 Error 和 RuntimeException 類(lèi)的子類(lèi)屬于非受查異常,除此之外繼承自 Exception 的類(lèi)型為受查異常。

異常的拋出與捕獲

直接拋出異常

通常,應(yīng)該捕獲那些知道如何處理的異常,將不知道如何處理的異常繼續(xù)傳遞下去。傳遞異??梢栽诜椒ê灻幨褂?strong> throws 關(guān)鍵字聲明可能會(huì)拋出的異常。

這應(yīng)該是全網(wǎng)講解JAVA 異常處理最全的文章了

 

封裝異常再拋出

有時(shí)我們會(huì)從 catch 中拋出一個(gè)異常,目的是為了改變異常的類(lèi)型。多用于在多系統(tǒng)集成時(shí),當(dāng)某個(gè)子系統(tǒng)故障,異常類(lèi)型可能有多種,可以用統(tǒng)一的異常類(lèi)型向外暴露,不需暴露太多內(nèi)部異常細(xì)節(jié)。

這應(yīng)該是全網(wǎng)講解JAVA 異常處理最全的文章了

 

捕獲異常

在一個(gè) try-catch 語(yǔ)句塊中可以捕獲多個(gè)異常類(lèi)型,并對(duì)不同類(lèi)型的異常做出不同的處理

這應(yīng)該是全網(wǎng)講解JAVA 異常處理最全的文章了

 

同一個(gè) catch 也可以捕獲多種類(lèi)型異常,用 | 隔開(kāi)

這應(yīng)該是全網(wǎng)講解JAVA 異常處理最全的文章了

 

自定義異常

習(xí)慣上,定義一個(gè)異常類(lèi)應(yīng)包含兩個(gè)構(gòu)造函數(shù),一個(gè)無(wú)參構(gòu)造函數(shù)和一個(gè)帶有詳細(xì)描述信息的構(gòu)造函數(shù)(Throwable 的 toString 方法會(huì)打印這些詳細(xì)信息,調(diào)試時(shí)很有用)

這應(yīng)該是全網(wǎng)講解JAVA 異常處理最全的文章了

 

try-catch-finally

當(dāng)方法中發(fā)生異常,異常處之后的代碼不會(huì)再執(zhí)行,如果之前獲取了一些本地資源需要釋放,則需要在方法正常結(jié)束時(shí)和 catch 語(yǔ)句中都調(diào)用釋放本地資源的代碼,顯得代碼比較繁瑣,finally 語(yǔ)句可以解決這個(gè)問(wèn)題。

這應(yīng)該是全網(wǎng)講解JAVA 異常處理最全的文章了

 

調(diào)用該方法時(shí),讀取文件時(shí)若發(fā)生異常,代碼會(huì)進(jìn)入 catch 代碼塊,之后進(jìn)入 finally 代碼塊;若讀取文件時(shí)未發(fā)生異常,則會(huì)跳過(guò) catch 代碼塊直接進(jìn)入 finally 代碼塊。所以無(wú)論代碼中是否發(fā)生異常,fianlly 中的代碼都會(huì)執(zhí)行。

若 catch 代碼塊中包含 return 語(yǔ)句,finally 中的代碼還會(huì)執(zhí)行嗎?將以上代碼中的 catch 子句修改如下:

這應(yīng)該是全網(wǎng)講解JAVA 異常處理最全的文章了

 

調(diào)用 readFile 方法,觀察當(dāng) catch 子句中調(diào)用 return 語(yǔ)句時(shí),finally 子句是否執(zhí)行

這應(yīng)該是全網(wǎng)講解JAVA 異常處理最全的文章了

 

可見(jiàn),即使 catch 中包含了 return 語(yǔ)句,finally 子句依然會(huì)執(zhí)行。若 finally 中也包含 return 語(yǔ)句,finally 中的 return 會(huì)覆蓋前面的 return.

try-with-resource

上面例子中,finally 中的 close 方法也可能拋出 IOException, 從而覆蓋了原始異常。JAVA 7 提供了更優(yōu)雅的方式來(lái)實(shí)現(xiàn)資源的自動(dòng)釋放,自動(dòng)釋放的資源需要是實(shí)現(xiàn)了 AutoCloseable 接口的類(lèi)。

這應(yīng)該是全網(wǎng)講解JAVA 異常處理最全的文章了

 

try 代碼塊退出時(shí),會(huì)自動(dòng)調(diào)用 scanner.close 方法,和把 scanner.close 方法放在 finally 代碼塊中不同的是,若 scanner.close 拋出異常,則會(huì)被抑制,拋出的仍然為原始異常。被抑制的異常會(huì)由 addSusppressed 方法添加到原來(lái)的異常,如果想要獲取被抑制的異常列表,可以調(diào)用 getSuppressed 方法來(lái)獲取。

阿里巴巴異常處理規(guī)約

1、【強(qiáng)制】 Java 類(lèi)庫(kù)中定義的可以通過(guò)預(yù)檢查方式規(guī)避的 RuntimeException 異常不應(yīng)該通過(guò)catch 的方式來(lái)處理,比如:NullPointerException, IndexOutOfBoundsException 等等。

說(shuō)明:無(wú)法通過(guò)預(yù)檢查的異常除外,比如,在解析字符串形式的數(shù)字時(shí),不得不通過(guò) catch NumberFormatException 來(lái)實(shí)現(xiàn)。

正例:if (obj != null) {…}

反例:try { obj.method(); } catch (NullPointerException e) {…}

2、【強(qiáng)制】 異常不要用來(lái)做流程控制,條件控制。

說(shuō)明: 異常設(shè)計(jì)的初衷是解決程序運(yùn)行中的各種意外情況,且異常的處理效率比條件判斷方式要低很多

3、【強(qiáng)制】 catch 時(shí)請(qǐng)分清穩(wěn)定代碼和非穩(wěn)定代碼,穩(wěn)定代碼指的是無(wú)論如何不會(huì)出錯(cuò)的代碼。對(duì)于非穩(wěn)定代碼的 catch 盡可能進(jìn)行區(qū)分異常類(lèi)型,再做對(duì)應(yīng)的異常處理。

說(shuō)明: 對(duì)大段代碼進(jìn)行 try-catch,使程序無(wú)法根據(jù)不同的異常做出正確的應(yīng)激反應(yīng),也不利于定位問(wèn)題,這是一種不負(fù)責(zé)任的表現(xiàn)。

正例: 用戶(hù)注冊(cè)的場(chǎng)景中,如果用戶(hù)輸入非法字符, 或用戶(hù)名稱(chēng)已存在, 或用戶(hù)輸入密碼過(guò)于簡(jiǎn)單,在程序上作出分門(mén)別類(lèi)的判斷,并提示給用戶(hù)。

4、【強(qiáng)制】 捕獲異常是為了處理它,不要捕獲了卻什么都不處理而拋棄之,如果不想處理它,請(qǐng)將該異常拋給它的調(diào)用者。最外層的業(yè)務(wù)使用者,必須處理異常,將其轉(zhuǎn)化為用戶(hù)可以理解的內(nèi)容。

5、【強(qiáng)制】 有 try 塊放到了事務(wù)代碼中, catch 異常后,如果需要回滾事務(wù),一定要注意手動(dòng)回滾事務(wù)。

6、【強(qiáng)制】 finally 塊必須對(duì)資源對(duì)象、流對(duì)象進(jìn)行關(guān)閉,有異常也要做 try-catch。

說(shuō)明: 如果 JDK7 及以上,可以使用 try-with-resources 方式。

7、【強(qiáng)制】 不要在 finally 塊中使用 return。

說(shuō)明:finally 塊中的 return 返回后方法結(jié)束執(zhí)行,不會(huì)再執(zhí)行 try 塊中的 return 語(yǔ)句。

8、【強(qiáng)制】 捕獲異常與拋異常,必須是完全匹配,或者捕獲異常是拋異常的父類(lèi)。

說(shuō)明: 如果預(yù)期對(duì)方拋的是繡球,實(shí)際接到的是鉛球,就會(huì)產(chǎn)生意外情況。

9、【推薦】 方法的返回值可以為 null,不強(qiáng)制返回空集合,或者空對(duì)象等,必須添加注釋充分說(shuō)明什么情況下會(huì)返回 null 值。

說(shuō)明: 本手冊(cè)明確防止 NPE 是調(diào)用者的責(zé)任。即使被調(diào)用方法返回空集合或者空對(duì)象,對(duì)調(diào)用者來(lái)說(shuō),也并非高枕無(wú)憂(yōu),必須考慮到遠(yuǎn)程調(diào)用失敗、 序列化失敗、 運(yùn)行時(shí)異常等場(chǎng)景返回null 的情況。

10、【推薦】 防止 NPE,是程序員的基本修養(yǎng),注意 NPE 產(chǎn)生的場(chǎng)景:

1)返回類(lèi)型為基本數(shù)據(jù)類(lèi)型, return 包裝數(shù)據(jù)類(lèi)型的對(duì)象時(shí),自動(dòng)拆箱有可能產(chǎn)生 NPE。

反例:public int f() { return Integer 對(duì)象}, 如果為 null,自動(dòng)解箱拋 NPE。

2) 數(shù)據(jù)庫(kù)的查詢(xún)結(jié)果可能為 null。

3) 集合里的元素即使 isNotEmpty,取出的數(shù)據(jù)元素也可能為 null。

4) 遠(yuǎn)程調(diào)用返回對(duì)象時(shí),一律要求進(jìn)行空指針判斷,防止 NPE。

5) 對(duì)于 Session 中獲取的數(shù)據(jù),建議 NPE 檢查,避免空指針。

6) 級(jí)聯(lián)調(diào)用 obj.getA().getB().getC(); 一連串調(diào)用,易產(chǎn)生 NPE。

正例: 使用 JDK8 的 Optional 類(lèi)來(lái)防止 NPE 問(wèn)題。

11、【推薦】 定義時(shí)區(qū)分 unchecked / checked 異常,避免直接拋出 new RuntimeException(),更不允許拋出 Exception 或者 Throwable,應(yīng)使用有業(yè)務(wù)含義的自定義異常。

推薦業(yè)界已定義過(guò)的自定義異常,如:DAOException / ServiceException 等。

12、【參考】 對(duì)于公司外的 http/api 開(kāi)放接口必須使用“錯(cuò)誤碼”; 而應(yīng)用內(nèi)部推薦異常拋出;跨應(yīng)用間 RPC 調(diào)用優(yōu)先考慮使用 Result 方式,封裝 isSuccess()方法、 “錯(cuò)誤碼”、 “錯(cuò)誤簡(jiǎn)短信息”。

說(shuō)明: 關(guān)于 RPC 方法返回方式使用 Result 方式的理由:

1) 使用拋異常返回方式,調(diào)用方如果沒(méi)有捕獲到就會(huì)產(chǎn)生運(yùn)行時(shí)錯(cuò)誤。

2) 如果不加棧信息,只是 new 自定義異常,加入自己的理解的 error message,對(duì)于調(diào)用端解決問(wèn)題的幫助不會(huì)太多。如果加了棧信息,在頻繁調(diào)用出錯(cuò)的情況下,數(shù)據(jù)序列化和傳輸?shù)男阅軗p耗也是問(wèn)題。

13、【參考】 避免出現(xiàn)重復(fù)的代碼(Don’t Repeat Yourself) ,即 DRY 原則。

說(shuō)明: 隨意復(fù)制和粘貼代碼,必然會(huì)導(dǎo)致代碼的重復(fù),在以后需要修改時(shí),需要修改所有的副本,容易遺漏。必要時(shí)抽取共性方法,或者抽象公共類(lèi),甚至是組件化。

正例: 一個(gè)類(lèi)中有多個(gè) public 方法,都需要進(jìn)行數(shù)行相同的參數(shù)校驗(yàn)操作,這個(gè)時(shí)候請(qǐng)抽?。簆rivate boolean checkParam(DTO dto) {…}

常見(jiàn)面試題

1. Error 和 Exception 區(qū)別是什么?

Error 類(lèi)型的錯(cuò)誤通常為虛擬機(jī)相關(guān)錯(cuò)誤,如系統(tǒng)崩潰,內(nèi)存不足,堆棧溢出等,編譯器不會(huì)對(duì)這類(lèi)錯(cuò)誤進(jìn)行檢測(cè),JAVA 應(yīng)用程序也不應(yīng)對(duì)這類(lèi)錯(cuò)誤進(jìn)行捕獲,一旦這類(lèi)錯(cuò)誤發(fā)生,通常應(yīng)用程序會(huì)被終止,僅靠應(yīng)用程序本身無(wú)法恢復(fù);

Exception 類(lèi)的錯(cuò)誤是可以在應(yīng)用程序中進(jìn)行捕獲并處理的,通常遇到這種錯(cuò)誤,應(yīng)對(duì)其進(jìn)行處理,使應(yīng)用程序可以繼續(xù)正常運(yùn)行。

2. 運(yùn)行時(shí)異常和一般異常區(qū)別是什么?

編譯器不會(huì)對(duì)運(yùn)行時(shí)異常進(jìn)行檢測(cè),沒(méi)有 try-catch,方法簽名中也沒(méi)有 throws 關(guān)鍵字聲明,編譯依然可以通過(guò)。如果出現(xiàn)了 RuntimeException, 那一定是程序員的錯(cuò)誤。

一般一場(chǎng)如果沒(méi)有 try-catch,且方法簽名中也沒(méi)有用 throws 關(guān)鍵字聲明可能拋出的異常,則編譯無(wú)法通過(guò)。這類(lèi)異常通常為應(yīng)用環(huán)境中的錯(cuò)誤,即外部錯(cuò)誤,非應(yīng)用程序本身錯(cuò)誤,如文件找不到等。

3.NoClassDefFoundError 和 ClassNotFoundException 區(qū)別?

NoClassDefFoundError 是一個(gè) Error 類(lèi)型的異常,是由 JVM 引起的,不應(yīng)該嘗試捕獲這個(gè)異常。

引起該異常的原因是 JVM 或 ClassLoader 嘗試加載某類(lèi)時(shí)在內(nèi)存中找不到該類(lèi)的定義,該動(dòng)作發(fā)生在運(yùn)行期間,即編譯時(shí)該類(lèi)存在,但是在運(yùn)行時(shí)卻找不到了,可能是變異后被刪除了等原因?qū)е拢?/p>

ClassNotFoundException 是一個(gè)受查異常,需要顯式地使用 try-catch 對(duì)其進(jìn)行捕獲和處理,或在方法簽名中用 throws 關(guān)鍵字進(jìn)行聲明。當(dāng)使用 Class.forName, ClassLoader.loadClass 或 ClassLoader.findSystemClass 動(dòng)態(tài)加載類(lèi)到內(nèi)存的時(shí)候,通過(guò)傳入的類(lèi)路徑參數(shù)沒(méi)有找到該類(lèi),就會(huì)拋出該異常;另一種拋出該異常的可能原因是某個(gè)類(lèi)已經(jīng)由一個(gè)類(lèi)加載器加載至內(nèi)存中,另一個(gè)加載器又嘗試去加載它。

4. JVM 是如何處理異常的?

在一個(gè)方法中如果發(fā)生異常,這個(gè)方法會(huì)創(chuàng)建一個(gè)一場(chǎng)對(duì)象,并轉(zhuǎn)交給 JVM,該異常對(duì)象包含異常名稱(chēng),異常描述以及異常發(fā)生時(shí)應(yīng)用程序的狀態(tài)。創(chuàng)建異常對(duì)象并轉(zhuǎn)交給 JVM 的過(guò)程稱(chēng)為拋出異常。可能有一系列的方法調(diào)用,最終才進(jìn)入拋出異常的方法,這一系列方法調(diào)用的有序列表叫做調(diào)用棧。

JVM 會(huì)順著調(diào)用棧去查找看是否有可以處理異常的代碼,如果有,則調(diào)用異常處理代碼。當(dāng) JVM 發(fā)現(xiàn)可以處理異常的代碼時(shí),會(huì)把發(fā)生的異常傳遞給它。如果 JVM 沒(méi)有找到可以處理該異常的代碼塊,JVM 就會(huì)將該異常轉(zhuǎn)交給默認(rèn)的異常處理器(默認(rèn)處理器為 JVM 的一部分),默認(rèn)異常處理器打印出異常信息并終止應(yīng)用程序。

5. throw 和 throws 的區(qū)別是什么?

throw 關(guān)鍵字用來(lái)拋出方法或代碼塊中的異常,受查異常和非受查異常都可以被拋出。

throws 關(guān)鍵字用在方法簽名處,用來(lái)標(biāo)識(shí)該方法可能拋出的異常列表。一個(gè)方法用 throws 標(biāo)識(shí)了可能拋出的異常列表,調(diào)用該方法的方法中必須包含可處理異常的代碼,否則也要在方法簽名中用 throws 關(guān)鍵字聲明相應(yīng)的異常。

6. 常見(jiàn)的 RuntimeException 有哪些?

  • ClassCastException(類(lèi)轉(zhuǎn)換異常)
  • IndexOutOfBoundsException(數(shù)組越界)
  • NullPointerException(空指針)
  • ArrayStoreException(數(shù)據(jù)存儲(chǔ)異常,操作數(shù)組時(shí)類(lèi)型不一致)
  • 還有IO操作的BufferOverflowException異常

分享到:
標(biāo)簽:異常 JAVA
用戶(hù)無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過(guò)答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定