歡迎光臨
每天分享高質量文章

乾貨分享|Java異常經典14問,你都能答對嗎?

精品專欄

 

1、什麼是Java中的異常?

異常是在程式執行期間可能發生的錯誤事件,並且會中斷它的正常流程。異常可能來自不同型別的情況,例如用戶輸入的錯誤資料,硬體故障,網絡連接故障等。

每當執行java陳述句時發生任何錯誤,都會創建一個異常物件,然後JRE會嘗試查找異常處理程式來處理異常。如果找到合適的異常處理程式,則將異常物件傳遞給處理程式代碼以處理異常,稱為捕獲異常。如果未找到處理程式,則應用程式將異常丟擲到運行時環境,JRE將終止該程式。

Java異常處理框架僅用於處理運行時錯誤,編譯時錯誤不由異常處理框架處理。

2、Java中的異常處理關鍵字是什麼?

java異常處理中使用了四個關鍵字。

throw:有時我們明確要創建異常物件然後丟擲它來停止程式的正常處理。throw關鍵字用於向運行時丟擲異常來處理它。

throws:當我們在方法中丟擲任何已檢查的異常而不處理它時,我們需要在方法簽名中使用throws關鍵字讓呼叫者程式知道該方法可能丟擲的異常。呼叫方法可以處理這些異常或使用throws關鍵字將其傳播給它的呼叫方法。我們可以在throws子句中提供多個異常,也可以與main()方法一起使用。

try-catch:我們在代碼中使用try-catch塊進行異常處理。try是塊的開始,catch是在try塊的末尾處理異常。我們可以使用try有多個catch塊,try-catch塊也可以嵌套。catch塊需要一個應該是Exception型別的引數。

finally:finally塊是可選的,只能用於try-catch塊。由於異常會暫停執行過程,因此我們可能會打開一些不會關閉的資源,因此我們可以使用finally塊。finally塊總是被執行,無論是否發生異常。

3、解釋Java異常層次結構?

Java異常是分層的,繼承用於對不同型別的異常進行分類。Throwable是Java Exceptions Hierarchy的父類,它有兩個子物件 – Error和Exception。異常進一步分為檢查異常和運行時異常。

錯誤是超出應用程式範圍的特殊情況,並且無法預測並從中恢復,例如硬體故障,JVM崩潰或記憶體不足錯誤。

Checked Exceptions是我們可以在程式中預期並嘗試從中恢復的特殊情況,例如FileNotFoundException。我們應該捕獲此異常並向用戶提供有用的訊息並正確記錄以進行除錯。Exception是所有Checked Exceptions的父類。

運行時異常是由錯誤的編程引起的,例如嘗試從Array中檢索元素。我們應該在嘗試檢索元素之前先檢查陣列的長度,否則它可能會ArrayIndexOutOfBoundException在運行時丟擲。RuntimeException是所有運行時異常的父類。

4、Java異常類的重要方法是什麼?

異常及其所有子類不提供任何特定方法,並且所有方法都在基類Throwable中定義。

  • String getMessage() – 此方法傳回訊息String of Throwable,並且可以在通過建構式創建異常時提供訊息。

  • String getLocalizedMessage() – 提供此方法,以便子類可以改寫它以向呼叫程式提供特定於語言環境的訊息。此方法getMessage()的可丟擲類實現只是使用方法來傳回異常訊息。

  • synchronized Throwable getCause() – 此方法傳回異常的原因或null id,原因未知。

  • String toString() – 此方法以String格式傳回有關Throwable的信息,傳回的String包含Throwable類和本地化訊息的名稱。

  • void printStackTrace() – 此方法將堆棧跟蹤信息打印到標準錯誤流,此方法已多載,我們可以將PrintStream或PrintWriter作為引數傳遞,以將堆棧跟蹤信息寫入檔案或流。

5、解釋Java 7 ARM功能和multi-catch塊?

如果你在一個try塊中捕獲了很多異常,你會發現catch塊代碼看起來非常難看,並且主要由冗餘代碼組成,以記錄錯誤,記住Java 7的一個特性是multi-catch塊。我們可以在一個catch塊中捕獲多個異常。具有此功能的catch塊如下所示:

  1. catch(IOException | SQLException | Exception ex){

  2.      logger.error(ex);

  3.      throw new MyException(ex.getMessage());

  4. }

大多數情況下,我們使用finally塊來關閉資源,有時我們忘記關閉它們併在資源耗盡時獲得運行時異常。這些異常很難除錯,我們可能需要查看我們使用該類資源的每個地方,以確保我們關閉它。所以java 7的改進之一是try-with-resources,我們可以在try陳述句中創建一個資源併在try-catch塊中使用它。當執行來自try-catch塊時,運行時環境會自動關閉這些資源。具有這種改進的try-catch塊樣本是:

  1. try (MyResource mr = new MyResource()) {

  2.         System.out.println("MyResource created in try-with-resources");

  3.     } catch (Exception e) {

  4.         e.printStackTrace();

  5.     }

6、Java中Checked和Unchecked Exception有什麼區別?

Checked Exceptions應該使用try-catch塊在代碼中處理,否則方法應該使用throws關鍵字讓呼叫者知道可能從方法丟擲的已檢查異常。未經檢查的異常不需要在程式中處理或在方法的throws子句中提及它們。

Exception是所有已檢查異常RuntimeException的超類,而是所有未經檢查的異常的超類。請註意,RuntimeException是Exception的子類。

已檢查的異常是需要在代碼中處理的錯誤方案,否則您將收到編譯時錯誤。例如,如果您使用FileReader讀取檔案,它會丟擲FileNotFoundException,我們必須在try-catch塊中捕獲它或將其再次拋給呼叫方法。

未經檢查的異常主要是由編程不良引起的,例如在物件取用上呼叫方法時的NullPointerException,而不確保它不為null。例如,我可以編寫一個方法來從字串中刪除所有元音。確保不傳遞空字串是呼叫者的責任。我可能會改變方法來處理這些場景,但理想情況下,呼叫者應該處理這個問題。

7、Java中throw和throws關鍵字有什麼區別?

throws關鍵字與方法簽名一起用於宣告方法可能丟擲的異常,而throw關鍵字用於破壞程式流並將異常物件移交給運行時來處理它。

8、如何在Java中編寫自定義異常?

我們可以擴展Exception類或其任何子類來創建我們的自定義異常類。自定義異常類可以擁有自己的變數和方法,我們可以使用它們將錯誤代碼或其他與異常相關的信息傳遞給異常處理程式。

自定義異常的一個簡單示例如下所示。

  1. package com.journaldev.exceptions;

  2. import java.io.IOException;

  3.     public class MyException extends IOException {

  4.     private static final long serialVersionUID = 4664456874499611218L;

  5.     private String errorCode="Unknown_Exception";

  6.     public MyException(String message, String errorCode){

  7.         super(message);

  8.         this.errorCode=errorCode;

  9.     }

  10.     public String getErrorCode(){

  11.         return this.errorCode;

  12.     }

  13. }

9、Java中的OutOfMemoryError是什麼?

Java中的OutOfMemoryError是java.lang.VirtualMachineError的子類,當JVM用完堆記憶體時,它會丟擲它。我們可以通過提供更多記憶體來通過java選項運行java應用程式來修複此錯誤。

$>java MyProgram -Xms1024m -Xmx1024m -XX:PermSize=64M -XX:MaxPermSize=256m

10、主執行緒中的異常”有哪些不同的情況?

一些常見的主執行緒異常情況是:

主執行緒java.lang.UnsupportedClassVersionError中的異常:

當您的java類是從另一個JDK版本編譯並且您嘗試從另一個Java版本運行它時,會出現此異常。

主執行緒java.lang.NoClassDefFoundError中的異常:

此異常有兩種變體。第一個是您提供類全名和.class擴展名的地方。第二種情況是找不到Class。

主執行緒java.lang.NoSuchMethodError中的異常:

main:當您嘗試運行沒有main方法的類時會出現此異常。

執行緒“main”中的異常java.lang.ArithmeticException:

每當從main方法丟擲任何異常時,它都會打印異常是控制台。第一部分解釋了從main方法丟擲異常,第二部分打印異常類名,然後在冒號後打印異常訊息。

11、Java中的final,finally和finalize有什麼區別?

final和finally是java中的關鍵字,而finalize是一種方法。

final關鍵字可以與類變數一起使用,以便它們不能被重新分配,類可以避免按類擴展,並且使用方法來避免子類改寫。

finally關鍵字與try-catch塊一起使用,以提供始終執行的陳述句即使出現一些異常,通常最終也會用來關閉資源。

finalize()方法由垃圾收集器在銷毀物件之前執行,這是確保關閉所有全域性資源的好方法。

在三者之中,最後只涉及到java異常處理。

12、當main方法丟擲異常時會發生什麼?

當main()方法丟擲異常時,Java Runtime終止程式併在系統控制臺中打印異常訊息和堆棧跟蹤。

13、我們可以有一個空的catch塊嗎?

我們可以有一個空的catch塊,但它是最差編程的例子。我們永遠不應該有空的catch塊,因為如果異常被該塊捕獲,我們將沒有關於異常的信息,並且它將成為除錯它的噩夢。應該至少有一個日誌記錄陳述句來記錄控制台或日誌檔案中的異常詳細信息。

14、提供一些Java異常處理最佳實踐?

與Java異常處理相關的一些最佳實踐是:

  1. 使用特定異常以便於除錯。

  2. 在程式中儘早丟擲異常(Fail-Fast)。

  3. 在程式後期捕獲異常,讓呼叫者處理異常。

  4. 使用Java 7 ARM功能確保資源已關閉或使用finally塊正確關閉它們。

  5. 始終記錄異常訊息以進行除錯。

  6. 使用multi-catch塊清潔關閉。

  7. 使用自定義異常從應用程式API中丟擲單一型別的異常。

  8. 遵循命名約定,始終以Exception結束。

  9. 記錄在javadoc中使用@throws的方法丟擲的異常。

  10. 異常是昂貴的,所以只有在有意義的時候丟擲它。否則,您可以捕獲它們並提供空或空響應。

MySQL的索引是什麼?怎麼優化?

在一個千萬級的資料庫查尋中,如何提高查詢效率?

你真的瞭解try{ return }finally{}中的return?

推薦四十多條純乾貨 Java 代碼優化建議

一個致命的 Redis 命令,導致公司損失 400 萬!!

美團三面:一個執行緒OOM,行程里其他執行緒還能運行麽?

設計樣式六大原則,你真的懂了嗎?

6 個實體詳解如何把 if-else 代碼重構成高質量代碼

END


>>>>>> 加群交流技術 <<<<<<

赞(0)

分享創造快樂

© 2021 知識星球   网站地图