簡體   English   中英

Java - checked vs unchecked異常 - 僅從代碼中說出來?

[英]Java - checked vs unchecked Exception - tell from code alone?

是否可以通過查看代碼來判斷異常類是已選中還是未選中? 我一直認為,如果它擴展了Exception,它被檢查,但是然后RuntimeException擴展了Exception並且未經檢查。 RuntimeException可能是彎曲該經驗法則的唯一類,其他未經檢查的異常如果不擴展RuntimeException則必須擴展Throwable。 但是,我沒有看到RuntimeException與Exception的區別。 我想知道是否在解釋器本身內部定義了差異?

RuntimeException及其子類是未經檢查的異常。 所有其他都是檢查例外。

您可以在Java教程中找到未經檢查的異常的定義(強調我的):

... Java編程語言不需要捕獲或指定未經檢查的異常的方法(RuntimeException,Error及其子類) ......

是否可以通過查看代碼來判斷異常類是已選中還是未選中?

是。 如果您知道規則...在JLS( 11.1.1 )中指定...並且您還可以查看異常超類的代碼(以便您可以檢查層次結構)。

規則是除了以下內容之外 “檢查”異常:

  • RuntimeException及其子類,和

  • Error及其子類,

這是“未經檢查”。

我想知道是否在解釋器本身內部定義了差異?

不,它在Java語言規范中。 實際上,JVM將已檢查和未檢查的異常視為相同。 所有檢查異常的檢查都是由Java編譯器完成的。


但是,我仍然不理解RuntimeException擴展Exception而不是Throwable的原因。 鑒於RuntimeException中沒有任何內容覆蓋Exception中定義的行為,因此該設計選擇似乎是矛盾的。

就是這樣。 此外,我沒有看到任何邏輯矛盾。

  • Error表示不可恢復的條件。 它沒有被檢查,因為沒有必要強迫應用程序對它做些什么。

  • Exception表示潛在的可恢復條件。

  • RuntimeException表示我們不希望強制應用程序處理的潛在可恢復條件。 (但它可以,如果它想)。

顯然,通過這種分類, RuntimeException >>是<< an Exception and >>而不是<< an Error ... ...這就是以這種方式定義異常類層次結構的基本原理。

它們被稱為“已檢查與未檢查”異常,而不是“被捕獲與未被捕獲” 在編譯時檢查異常是受控制的,即如果某些內容不符合異常合同,編譯器會發出警告,但是在運行時可以拋出未經檢查的異常。

如果你使用IDE是最簡單的方法,如果你的IDE給你一個錯誤/下划線,告訴你如果你沒有抓住它就有一個未處理的異常。 這些是檢查異常。

或者,取消選中從RuntimeException繼承的任何內容。

Throwable的繼承樹實際上是:

Throwable     Error
              Exception   RuntimeException

拋出任何擴展ErrorRuntimeException都不需要聲明。 錯誤通常僅由JVM拋出,並發出非常糟糕的信號。

任何擴展Exception但不擴展RuntimeException都需要聲明。 一般來說, Exceptions是調用代碼應該處理或考慮的事情(例如“無法打開文件”),而RuntimeExceptions可能表示代碼中的錯誤或損壞的數據,如NullPointerException ,因此調用不太可能代碼可以做任何事情。

如果您使用任何明確throws exception方法或代碼,您需要捕獲該異常,並且通過查看代碼,我們確定需要捕獲,因此檢查此Exception 如果RuntimeException通過查看代碼,您無法保證此代碼將拋出異常,因此它們未被選中。

Java doc參考

方法拋出的任何異常都是方法的公共編程接口的一部分。 那些調用方法的人必須知道方法可以拋出的異常,以便他們可以決定如何處理它們。 這些異常與該方法的編程接口一樣,也是其參數和返回值的一部分。

正如javadoc所述:

RuntimeException是在Java虛擬機的正常操作期間可以拋出的那些異常的超類。 一個方法不需要在其throws子句中聲明RuntimeException的任何子類,這些子類可能在方法執行期間拋出但未捕獲。

作者:Frank Yellin

自:JDK1.0

現在,回到你的問題, I wonder if the difference is defined inside the interpreter itself? ....魔術技巧是在字節碼內完成的。

下面的文章通過分析字節碼來顯示它:

http://www.javaworld.com/article/2076868/learn-java/how-the-java-virtual-machine-handles-exceptions.html

基本的機制是異常表

Exception table:
   from   to  target type
     0     4     4   <Class java.lang.ArithmeticException>

如果在執行方法期間拋出異常,Java虛擬機將在異常表中搜索匹配的條目。

如果當前程序計數器在條目指定的范圍內,並且拋出的異常類是由條目指定的異常類(或者是指定異常類的子類),則異常表條目匹配。

Java虛擬機按照條目在表中的顯示順序搜索異常表。 找到第一個匹配項后,Java虛擬機會將程序計數器設置為新的pc偏移位置並繼續執行。

如果未找到匹配項,Java虛擬機將彈出當前堆棧幀並重新拋出相同的異常。

當Java虛擬機彈出當前堆棧幀時,它會有效地中止當前方法的執行並返回調用此方法的方法。 但是,不是在前一個方法中繼續正常執行,而是在該方法中拋出相同的異常,這會導致Java虛擬機經歷搜索該方法的異常表的相同過程。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM