[英]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
拋出任何擴展Error
或RuntimeException
都不需要聲明。 錯誤通常僅由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?
....魔術技巧是在字節碼內完成的。
下面的文章通過分析字節碼來顯示它:
基本的機制是異常表 :
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.