2011-06-10 190 views
1

我在Java中的一些方法拋出異常,如NoSuchElementException,IllegalArgumentException等,但使用這些方法時,這些異常似乎未被選中。換句話說,我的方法的調用者不需要對拋出這些異常的方法進行try/catch。我周圍看來,它似乎是默認情況下的「檢查」,只有錯誤是「未選中」。但不知何故,我拋出的例外也未被檢查。真奇怪。拋出已檢查的異常

如何確保當我的方法拋出異常時,調用者必須在編譯時捕獲異常?簡單地說,我怎樣才能拋出一個檢查異常?

謝謝!

回答

6

只有RuntimeException及其子類沒有選中。 (嗯,Error及其子類也是如此,但是你不應該混淆Error s)。你只需要做一個檢查異常就可以確保它不會延伸RuntimeException

0

擴展RuntimeException的異常不必聲明。

您可以聲明方法:throws Exception或甚至throws Throwable並且必須處理(儘管不建議)。

3

是否檢查異常是否爲不是如何拋出或聲明它,只取決於您選擇的異常是否從RuntimeException派生。上面列出的那些都是從RuntimeException派生的,因此您的方法的客戶端不需要捕獲它們。

1

我認爲你應該退後一步,學習背後的理論爲什麼要拋出一個檢查異常與未檢查的異常。關於異常的Java tutorial是一個很好的資源。

從有權Unchecked Exceptions — The Controversy頁:

運行時異常表示是一個規劃問題的結果,因此,該API的客戶端代碼不能合理地期望從中進行恢復或處理他們的問題任何方式。

2

檢查Throwable的所有子類,除了Error和RuntimeException的子類外。 (你可以直接子類Throwable)

編譯器檢查這些異常,但是它們在運行時沒有特殊的地方。即您可以在編譯器不知道的情況下拋出一個checked異常,並且它將正常運行。

例如

public static void throwChecked(Throwable t) /* no throws clause */ { 
    Thread.currentThread().stop(t); 
} 

public static void main(String... args) /* no throws clause */ { 
    throwChecked(new Throwable()); 
} 

這可編譯和打印Throwable,如您所期望的那樣。

+0

此方法在十多年前不推薦使用,將在未來版本中刪除。不應該被使用。 https://docs.oracle.com/javase/9​​/docs/api/java/lang/Thread.html#stop-java.lang.Throwable- – 2017-10-22 09:07:35

+0

@ Miha_x64它已在Java 8中禁用。還有其他方式做同樣的事情,這個答案應該更新。 – 2017-10-22 10:41:04

1

看到這個hack,它可能會幫助(希望它不是OT)。

public class Test { 

    // No throws clause here 
    public static void main(String[] args) { 
     doThrow(new SQLException()); 
    } 

    static void doThrow(Exception e) { 
     Test.<RuntimeException> doThrow0(e); 
    } 

    @SuppressWarnings("unchecked") 
    static <E extends Exception> void doThrow0(Exception e) throws E { 
     throw (E) e; 
    } 
}