[Java學習筆記] Java異常機制(也許是全網最獨特視角)

来源:https://www.cnblogs.com/ForJoy/archive/2022/07/16/16452920.html
-Advertisement-
Play Games

Java 異常機制(也許是全網最獨特視角) 一、Java中的“異常“指什麼 什麼是異常 一句話簡單理解:異常是程式運行中的一些異常或者錯誤。 (純字面意思) Error類 和 Exception類 Java中“萬物皆對象”,異常也不例外, Java把異常當做對象來處理,並將異常分為兩大類——Erro ...


Java 異常機制(也許是全網最獨特視角)

一、Java中的“異常“指什麼

  • 什麼是異常

    一句話簡單理解:異常是程式運行中的一些異常或者錯誤。

    (純字面意思)

  • Error類 和 Exception類

    Java中“萬物皆對象”,異常也不例外,

    Java把異常當做對象來處理,並將異常分為兩大類——Error(錯誤)和Exception(異常),它們都是Throwable類的子類。

    這裡看起來可能有點奇怪,什麼叫“把異常分為錯誤和異常兩類”??可以這樣粗暴地理解——異常有兩大類,一類是錯誤異常(Error),另一類是異常異常(Exception)

    至於為什麼這麼奇怪,我覺得既有翻譯的問題,也有Java文檔沒說清楚的問題。(主要是翻譯的鍋)

    Oracle的JavaSE官方文檔是這樣說的:

    An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions.

    The class Exception and its subclasses are a form of Throwable that indicates conditions that a reasonable application might want to catch.

    所以個人見解,我們可以把Throwable這個類翻譯為“事故類 ”(單詞problem:問題、狀況、事故),這個“事故類”的對象具有可被拋出的性質,且”事故類“Throwable有兩個子類“錯誤事故”(Error,對應致命的大事故)和"異常事故"(Exception,對應剩餘可以處理的事故)。

    所以Java的“異常機制”這個翻譯很容易誤導人,讓人奇怪什麼叫異常包括錯誤和異常,EXception的異常和“異常機制”的異常,這兩個翻譯衝突了,所以我認為更應該翻譯為Java的“事故機制”。

    Error類的常見子類有IOError、AWTError、VirtualMachineError等,

    Exception類的常見子類有IOException、RuntimeException等。

  • Error和Exception的區別

    Error通常是災難性的致命錯誤,是程式無法控制和處理的,當出現這類異常時,JVM一般會選擇終止線程;而Exception通常情況下是可以被程式處理的,並且在程式中應該儘可能的去處理這類異常。

    個人總結:曾經糾結Error和Exception的區別糾結了好久,後來發現根本不用糾結,就當成一樣的東西就好了,都是“意外狀況”,只不過一個嚴重點一個不嚴重點而已。由於Error是嚴重的異常,對於程式已經致命了,所以並不需要捕獲(catch)或者聲明(throws),而Exception屬於不那麼嚴重,還可以“輓救”或者說“預判”的異常,所以可以被捕獲(catch)或者聲明(throws)來做出進一步處理。


二、異常的捕獲和拋出

  • 異常處理的五個關鍵字——try、catch、finally、throw、throws。

    • try 和 catch 關鍵字可以捕獲異常。

      try/catch 代碼塊放在異常可能發生的地方,try 代碼塊中的代碼會先被執行,catch 語句包含要捕獲異常類型的聲明。當 try 語句中的代碼發生一個異常時,try 後面的 catch 塊就會被檢查,如果發生的異常是catch語句所聲明的異常類型的實例,則該異常會被傳遞到該 catch 塊並執行catch代碼塊中的代碼,類似於傳遞一個參數到方法中。

      finally代碼塊出現在catch代碼塊之後,無論try代碼塊中是否發生異常,finally代碼塊中的代碼總會被執行。

      註意:1、try代碼塊後必須有catch代碼塊或者finally代碼塊;

      ​ 2、靠上的catch所聲明的異常類型不能是靠下的catc所聲明的異常類型的父類(如以下代碼中,e1不是e2的父類)。

      try{
          //正常執行的代碼
      }catch(Exception1 e1){
          //捕獲到Exception1類的異常後執行的代碼
          //捕獲到的異常被賦值給e1
      }catch(Exception2 e2){
          //捕獲到Exception2類的異常後執行的代碼
        //捕獲到的異常被賦值給e2
      }finally{
          //善後代碼
      }
      
    • throw 和 throws 關鍵字用於主動拋出異常。

      兩個關鍵字的區別是,throw用於拋出一個異常,而throws用於聲明方法可能拋出的異常。

      throw只能拋出一個異常對象,throws可以聲明多個可能發生的異常類。

      即一個負責拋出,一個負責聲明。

      註意:1、若方法中有 異常(嚴格來說是檢查異常,詳見後文)拋出,必須使用throws語句在方法頭處聲明異常,或者在方法體內使用try/catch語句將異常拋出語句包圍(將throw語句置於try代碼塊中);

      ​ 2、若一個方法使用了throws語句聲明異常,則引用此方法的另一個方法必須使用throws語句在方法頭處聲明異常,或者使用try/catch語句將引用此方法的語句包圍(將引用此方法的語句置於try代碼塊中)

      public void test1(){
          //使用try/catch語句處理異常
          try{
              throw new Exception();
          }catch(Exception e){
              System.out.println("Thers's an exception.")
          }
      }
      
      public void test2() throws Exception{
          //使用throws語句在方法頭處聲明異常
          throw new Exception();
      }
      
      public void test3() throws Exception{
          //引用test2也要聲明異常
          test2();
      }
      
      public void test4() throws Exception{
          //引用test2也要聲明異常
          
      

      總結:可以這樣理解,throw就是拋出異常,try/catch就是處理異常,throws就是暫時不處理、交給引用自己的方法處理。

  • 檢查異常(checked exception)和非檢查異常(unchecked exception)

    檢查異常:除了Error類及其子類 和 RuntimeException類及其子類,其它的Throwable子類都是檢查異常。

    非檢查異常:Error類及其子類 和 RuntimeException類及其子類。

    檢查異常是編譯器要求程式必須處置的異常,這種異常的特點是Java編譯器會檢查它是否被捕獲(try/catch)或者聲明(throws),否則編譯不通過。非檢查異常是編譯器不要求強制處理的異常。

    public viod test(){
        //拋出Error類對象但並不做處理,編譯也能通過。
        throw new Error();
    }
    public viod test(){
        //拋出RuntimeException類對象但並不做處理,編譯也能通過。
        throw new RuntimeException();
    }
    //Error類及其子類 和 RuntimeException類及其子類 都是非檢查異常,
    
  • 運行時異常和非運行時異常

    運行時異常:RuntimeException類及其子類。

    非運行時異常:RuntimeException以外的Exception類及其子類。

    其實運行時異常就是 除去Error類的非檢查異常,

    如果我們不去處理運行時異常,JVM會接管處理,系統會把異常一直往上層拋,一直到最上層,

    最上層拋出之後,如果拋出異常線上程中,這個線程就會退出,如果拋出異常在主程式中,整個程式就退出了。

    也就是說,如果不對運行時異常進行處理,程式會通過編譯並運行,出現運行時異常後,要麼是線程終止,要麼是主程式終止。

    public class Draft {
        public static void test1(){
            throw new RuntimeException();
        }
        public static void test2(){
            test1();
        }
        public static void main(String[] args) {
            test2();
        }
    }
    

    運行以上代碼,終端會出現以下結果,

    Exception in thread "main" java.lang.RuntimeException
    at Draft.test1(Draft.java:3)
    at Draft.test2(Draft.java:6)
    at Draft.main(Draft.java:9)

三、自定義異常

  • 如果Java提供的內置異常類型不能滿足程式設計的需求,我們可以自定義異常類,只需要繼承Exception類或者它的子類,以上異常機制對自定義的異常類同樣適用。

呼,終於寫完咯!人生第一篇博客,歡迎各路大佬指正!

此後會持續更新學習筆記,每一篇都會用心去寫去感悟。

原創聲明:本文完全為作者蘭勃基尼原創,轉載請聲明並附上原文鏈接https://www.cnblogs.com/ForJoy/p/16452920.html。作者各平臺用戶名如下

知乎:我求知若渴呀

博客園:蘭勃基尼_CodeJoy

CSDN:蘭勃基尼_CodeJoy


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

-Advertisement-
Play Games
更多相關文章
  • 摘要:最近看《電腦體繫結構:量化研究方法(第五版)》,發現指令集設計中的一些原則,對API設計也同樣適用,給大家分享一下。 本文中的所有內容來自工作和學習過程中的心得整理,如需轉載請註明出處。周榮華@燧原科技 1 正交 指令集需要滿足操作、數據類型和定址方式三個方面的功能就是正交的。所以API設計 ...
  • 本章是系列文章的第十一章,主要介紹GPU的編譯原理,分析了多核運行過程中的記憶體分岔和控制流分岔的分析和處理。 本文中的所有內容來自學習DCC888的學習筆記或者自己理解的整理,如需轉載請註明出處。周榮華@燧原科技 11.1 什麼是GPU 11.1.1 GPU的發展歷史 軟體控制的VGA幀緩衝區 頻繁 ...
  • Twitter系統架構參考Push、Pull模式每時每刻都有用戶在Twitter上發表內容,Twitter工作是規劃如何組織內容並把它發送用戶的粉絲。 實時是真正的挑戰,5秒內將消息呈現給粉絲是現階段的目標。 投遞意味著內容、投入互聯網,然後儘可能快的發送接收。 投遞將歷時數據放入存儲棧,推送通知, ...
  • 環境介紹: dubbo的版本是比較舊的版本, 肯定是小於2.5的, jdk版本是1.7, 預設使用的是HotSpot虛擬機 前提說明: dubbo版本應該就是最原始的2.x的版本, 由於在這個基礎上公司還經過了自己的自定義封裝, 所以升級的話肯定是沒戲的, 其次, 也是由於某些模塊很少使用到, 所以 ...
  • 認識Ioc容器和Servlet容器 1.介紹loC容器 loC (Inversion of Control)容器,是面向對象編程中的一種設計原則,意為控制反轉(也被 稱為'控制反向”或"控制倒置”)。它將程式中創建對象的控制權交給Spring框架來管理,以便降低電腦代碼之間的耦合度。 控制反轉的實 ...
  • 數組 數組存儲相同類型值的序列。 聲明數組 數組是一種數據結構,用來存儲同一類型值的集合。通過一個整型下標(index,或稱索引)可以訪問數組中的每一個值。例如,如果a是一個整型數組,a[i]就是數組中下標為i的整數。 在聲明數組變數時,需要指出數組類型(數據元素類型緊跟[])和數組變數的名字。下麵 ...
  • 啥是倍增思想? 倍增,每次將範圍擴大或減少一倍而達到加速的效果 舉個慄子,你想要跳到15米遠的地方,你怎麼找到這個15這個地方,一步一步跳嗎,利用倍增的話 預設一個k使2^k>15值 ,這裡我們假設k=5, 2^5=32 >15 k- -; k=4; 跳過了,不跳 2^4=16 >15 k- -; ...
  • 大數 如果基本的整數和浮點數精度不能夠滿足需求,那麼可以使用java.math包中兩個很有用的類:BigInteger和BigDecimal。這兩個類可以處理包含任意長度數字序列的數值。BigInteger類實現任意精度的整數運算,BigDecimal實現任意精度的浮點數運算。 使用靜態的value ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...