簡體   English   中英

是否可以在沒有任何拋出指令的情況下隱式拋出已檢查的異常?

[英]Is it possible to throw an checked Exception implicitly, without any athrow instruction?

在 Java 中,已檢查異常和未檢查異常都可以顯式拋出,即通過throw語句。 此外,像ArithmeticExceptionOutOfMemoryError這樣的未經檢查的異常可以在沒有任何明確的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異常(選中或未選中)。

  1. 您可以調用Unsafe.throwException(Throwable)

  2. 在本機代碼中,您可以調用 JNI API 中的ThrowThrowNew函數。

在這兩種情況下,您都可以規避 Java(編譯時和驗證程序)檢查,這些檢查旨在確保始終聲明(通過throws子句)或處理檢查的異常。

注意使用Unsafe或本機代碼意味着您的代碼不是純 Java。 它不會是便攜式的。 此外,很容易造成 JVM 不穩定。 JVM 崩潰並不罕見。


此外, athrow本身會在沒有拋出指令的情況下拋出異常。 例如,如果您嘗試使用new FileInputStream打開一個不存在的文件並拋出FileNotFoundException ,則它是從本機代碼中拋出的,而不是從編譯的 Java 代碼中拋出的。

因此,您的應用程序可以使用此機制隱式拋出許多已檢查和未檢查的異常; 例如,故意試圖打開一個不存在的文件。 但是, read的方法簽名聲明它可能會拋出IOException ,因此編譯器知道這一點......從檢查的異常規則的角度來看。


1 - 如果你的應用程序設計需要這種瘋狂,你會被建議想出一個替代方案。 嘗試與 Java 的檢查異常規則作斗爭是個壞主意。 如果您非常不喜歡它們以至於您正在考慮這樣做,那么您應該選擇一種不同的編程語言。

在 java 字節碼中,這僅適用於 JVM 可以自行生成的異常,但IOException不是其中之一。 您只能使用虛擬機拋出由解釋字節碼拋出的運行時異常。 例如這段代碼:

aconst_null
monitorexit

將拋出NullPointerException 理論上,這對於像NegativeArraySizeExceptionIllegalMonitorStateExceptionWrongMethodTypeExceptionBootstrapMethodErrorIncompatibleClassChangeError和許多其他的 throwable 也是可能的。 你可以 在這里找到更多

暫無
暫無

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

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