[英]Is it possible to throw an checked Exception implicitly, without any athrow instruction?
在 Java 中,已檢查異常和未檢查異常都可以顯式拋出,即通過throw
語句。 此外,像ArithmeticException
和OutOfMemoryError
這樣的未經檢查的異常可以在沒有任何明確的throw
語句的情況下觸發,如下所示:
public static void throwArithmeticException() {
int i = 1;
int j = i / 0;
}
public static void throwOutOfMemoryError() {
List<Object> list = new ArrayList<>();
while(true) {
list.add(new Object());
}
}
所以我的問題是,有什么方法可以隱式觸發檢查的異常,例如IOException
,即不使用任何throw
語句?
你可以做到,但你不應該1 。
我假設您正在談論athrow
字節碼指令。 (而且您真的問是否可以在不使用throw
語句的情況下從代碼中觸發異常。)
應用程序有(至少)兩種方法可以拋出不涉及顯式拋出指令的任意athrow
異常(選中或未選中)。
您可以調用Unsafe.throwException(Throwable)
。
在本機代碼中,您可以調用 JNI API 中的Throw
或ThrowNew
函數。
在這兩種情況下,您都可以規避 Java(編譯時和驗證程序)檢查,這些檢查旨在確保始終聲明(通過throws
子句)或處理檢查的異常。
注意使用Unsafe
或本機代碼意味着您的代碼不是純 Java。 它不會是便攜式的。 此外,很容易造成 JVM 不穩定。 JVM 崩潰並不罕見。
此外, athrow
本身會在沒有拋出指令的情況下拋出異常。 例如,如果您嘗試使用new FileInputStream
打開一個不存在的文件並拋出FileNotFoundException
,則它是從本機代碼中拋出的,而不是從編譯的 Java 代碼中拋出的。
因此,您的應用程序可以使用此機制隱式拋出許多已檢查和未檢查的異常; 例如,故意試圖打開一個不存在的文件。 但是, read
的方法簽名聲明它可能會拋出IOException
,因此編譯器知道這一點......從檢查的異常規則的角度來看。
1 - 如果你的應用程序設計需要這種瘋狂,你會被建議想出一個替代方案。 嘗試與 Java 的檢查異常規則作斗爭是個壞主意。 如果您非常不喜歡它們以至於您正在考慮這樣做,那么您應該選擇一種不同的編程語言。
在 java 字節碼中,這僅適用於 JVM 可以自行生成的異常,但IOException
不是其中之一。 您只能使用虛擬機拋出由解釋字節碼拋出的運行時異常。 例如這段代碼:
aconst_null
monitorexit
將拋出NullPointerException
。 理論上,這對於像NegativeArraySizeException
、 IllegalMonitorStateException
、 WrongMethodTypeException
、 BootstrapMethodError
、 IncompatibleClassChangeError
和許多其他的 throwable 也是可能的。 你可以 在這里找到更多
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.