【Java面試指北】Exception Error Throwable 你分得清麽?

来源:https://www.cnblogs.com/shuofxz/archive/2022/12/04/16949218.html
-Advertisement-
Play Games

讀本篇文章之前,如果讓你敘述一下 Exception Error Throwable 的區別,你能回答出來麽? 你的反應是不是像下麵一樣呢? 你在寫代碼時會經常 try catch(Exception) 在 log 中會看到 OutOfMemoryError Throwable 似乎不常見,但也大概... ...


讀本篇文章之前,如果讓你敘述一下 Exception Error Throwable 的區別,你能回答出來麽?
你的反應是不是像下麵一樣呢?

  • 你在寫代碼時會經常 try catch(Exception)
  • 在 log 中會看到 OutOfMemoryError
  • Throwable 似乎不常見,但也大概聽說過

一、Exception Error Throwable 關係

直接看下圖,展示了三者之間的關係:

  • ThrowableErrorException 的父類。
  • Exception是程式正常運行中可預料的正常情況,應該被捕獲併進行處理。
    • 又分為可檢查(checked)不檢查(unchecked)異常。
    • 可檢查異常是在編譯期檢查的一部分,必須顯示捕獲處理。如有的方法 throw exception,那麼調用該函數則必須 catch 處理或者再次 throw 出去交給下一層處理。
    • 不檢查異常一般指運行時異常(RuntimeException),類似 ArrayIndexOutOfBoundsExceptionArithmeticException等。一般可由代碼邏輯避免,可看情況是否捕獲。
  • Error 一般是正常情況下不太可能出現的,絕大部分 Error 會導致程式處於不可恢復的狀態,所以也不必捕獲。如 OutOfMemoryError

image.png

二、對比一個 Error 和 Exception

你在面試中也許會被問到:

NoClassDefFoundError 和 ClassNotFoundException 有什麼區別?

首先,我們看這倆名字,一個是 Error 另一個是 Exception,從上面的介紹以及看下麵的繼承圖可以得到:ClassNotFoundException 應是編碼時要被捕獲的異常,NoClassDefFoundError 是編譯通過了,但運行時產生的重大問題。
image.png

進一步的:
ClassNotFoundException 是運行中動態載入類時出現的問題。
舉例來說,使用 Class.forName 來動態載入一個類,如果你不顯示的 catch 處理,ide 都會給你提示,並且也過不了編譯。

// 錯誤寫法
public void except() {
    Class.forName("com.test.aaa");
}

// 正確寫法
public void except() {
    try {
        Class.forName("com.test.aaa");
    } catch (ClassNotFoundException e) {
        // throw or log
        throw new RuntimeException(e);
        // log.error("ClassNotFoundException: ", e);
    }
}

image.png

NoClassDefFoundError 是編譯時沒問題,但運行時 new 實例找不到。
比如在一個類中引用另一個類的函數,編譯後把另一個類的 class 文件刪掉:

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello world!");
        MyPrint.printName();
    }
}
public class MyPrint {
    public static void  printName() {
        System.out.println("my name is zhangsan");
    }
}

使用 javac 編譯,再刪除 MyPrint.class

$ tree com
com
└── shuofxz
    ├── Main.class
    ├── Main.java
    ├── MyPrint.class  # 把這個文件刪掉
    └── MyPrint.java

執行程式,就會看到 NoClassDefFoundError,並且是由 ClassNotFoundException 引起的。

Exception in thread "main" java.lang.NoClassDefFoundError: com/shuofxz/MyPrint
	at com.shuofxz.Main.main(Main.java:6)
Caused by: java.lang.ClassNotFoundException: com.shuofxz.MyPrint
	at java.net.URLClassLoader.findClass(URLClassLoader.java:387)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:419)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:352)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:352)
	... 1 more

三、捕獲異常代碼常見問題

一)看下麵的代碼有什麼問題?

try {
  // 業務代碼
  // ...
  Thread.sleep(1000L);
} catch (Exception e) {
}
  • 捕獲了過於通用的異常 Exception,應改為對應的 InterruptedException。這麼做的目的是因為:第一方便閱讀代碼,知道可能會出現什麼具體的異常;第二不捕獲意料之外的異常。
  • 不要捕獲異常之後啥都不做(生吞異常)。這就是給自己挖坑,之後程式遇到問題,你很難定位到這裡。

二)再看下麵這個,增加了異常列印邏輯,還有什麼問題不?

try {
    // 業務代碼
    // …
} catch (IOException e) {
    e.printStackTrace();
}
  • 自娛自樂是 ok 的,但不要放到生產環境中。因為 e.printStackTrace() 的功能是:Prints this throwable and its backtrace to the standard error stream。你很難判斷它到底輸出到哪裡去了。
  • 應該用成熟的日誌工具如 Slf4j 等。

三)再來看下麵的:

try {
    // 業務邏輯 A
    // 業務邏輯 B
    // 業務邏輯 C
    // ...
} catch (Exception e) {
    log.error("have exception", e);
}
  • 不能因為怕丟失異常捕獲,就把一大段代碼都框到一個 try-catch 模塊中。
  • try-catch 代碼段會產生額外的性能開銷,它往往會影響 JVM 對代碼進行優化。

四)我們前面介紹了Exception、Error、Throwable,為什麼代碼中經常能看到 catch XXException,卻幾乎看不到 catch XXErrorcatch Throwable 呢?

  • Exception 才是你應該關註處理的異常,這種異常處理後還可以使程式正常運行。
  • Error 屬於重大問題,是會使程式直接崩潰的,你捕獲了也沒什麼用,很難讓程式再「活」過來。
  • 至於 Throwable,首先不應該不過這麼寬泛的問題(比捕獲 Exception 還嚴重),第二其中包含了 Error 也不是你應該處理的問題。
  • 因此,Error 和 Throwable 除非你明確知道你在乾什麼,否則不要捕獲這兩種。

三、小結

本篇介紹了 Exception Error Throwable 的區別,並給出了相關例子幫助理解。
回到開頭的問題:「敘述一下 Exception Error Throwable 的區別」你心裡有數了麽?


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Linux 命令及其參數繁多,大多數人都是無法記住全部功能和具體參數意思的。在 linux 終端,面對命令不知道怎麼用,或不記得命令的拼寫及參數時,我們需要求助於系統的幫助文檔; linux 系統內置的幫助文檔很詳細,通常能解決我們的問題,我們需要掌握如何正確的去使用它們。 ...
  • Linux系統環境監測 Linux系統環境主要監測CPU、記憶體、磁碟I/O和網路流量。 1. CPU (1) 查看CPU的負載情況:uptime 可以通過uptime查看系統整體的負載情況。 如果伺服器的CPU為1核心,則1分鐘的系統平均負載 >=3 說明負載過高,如果伺服器的CPU為4核心,則lo ...
  • 1.2 Hadoop簡介 1.2.1 什麼是Hadoop ​ Hadoop 是一個適合大數據的分散式存儲和計算平臺 ​ 如前所述,狹義上說Hadoop就是一個框架平臺,廣義上講Hadoop代表大數據的一個技術生態 圈,包括很多其他軟體框架 ​ Hadoop生態圈技術棧 ​ Hadoop(HDFS + ...
  • 導讀: 今天為大家介紹京東零售大數據的雲原生平臺化實踐,主要包括以下幾大方面內容: 雲原生的定義和理解 雲原生相關技術的演化 京東大數據在雲原生平臺化上的實踐 雲原生應用平臺的發展 分享嘉賓:劉仲偉 京東 架構師 編輯整理:張明宇 廣州某銀行 出品社區:DataFun 01/雲原生的定義和理解 1. ...
  • 一、學習路線 1.HTML5+CSS3 黑馬程式員pink老師前端入門教程,零基礎必看的h5(html5)+css3+移動端前端視頻教程_嗶哩嗶哩_bilibili 2.JavaScript JavaScript基礎語法-dom-bom-js-es6新語法-jQuery-數據可視化echarts黑馬 ...
  • JQuery03 4.jQuery選擇器03 4.4表單選擇器 應用實例 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>表單選擇器應用實例</title> <script type="text/javasc ...
  • 一、什麼是防禦式編程 防禦性編程是一種細緻、謹慎的編程方法(習慣)。我們在寫代碼時常會有“以防萬一”的心態,把以防萬一有可能出現的情況提前考慮進去,規避以免以防萬一齣現帶來的問題。 應用防禦性編程技術,你可以偵測到可能被忽略的錯誤,防止可能會導致災難性後果的“小毛病”的出現,在時間的運行過程中為你節 ...
  • 散耦合的架構是一種軟體應用程式開發模式,其中多個組件相互連接,但並不嚴重依賴對方。這些組件共同創建了一個總的網路或系統,儘管每個服務都是為執行單一任務而創建的獨立實體。鬆散耦合架構的主要目的是創建一個不會因為單個組件的失敗而失敗的系統。面向服務的架構(SOA)通常由鬆散耦合的架構組成。 鬆散耦合架構 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...