2013-02-14 36 views
3

Java編譯器如何知道java.lang.RuntimeException及其子類未被選中,因爲它們從java.lang.Exception繼承,這是一個檢查的異常?我研究了代碼,看起來不是類中的任何東西,它告訴編譯器。Java如何知道RuntimeExceptions未被選中?

+0

因爲它'知道'寫在JLS中的內容,而不僅僅是類層次結構中的內容。 – EJP 2013-02-15 03:59:17

回答

8

因爲它是在specification of the language # 11.1.1定義方式:

  • 未經檢查的異常類是運行時異常類和錯誤類。
  • 檢查的異常類是除未經檢查的異常類以外的所有異常類。也就是說,檢查的異常類是除了RuntimeException及其子類和Error及其子類之外的Throwable的所有子類。

所以它不是各種異常類的代碼的一部分,它是編譯器必須實現的兼容,僅是語言定義的一個慣例。

+0

建立在@assylias寫道:所有的Java編譯器必須檢測到一個'java.lang.RuntimeException'正在使用,並做內部需要做的任何事情來從「checked」轉到「unchecked」。源代碼不會告訴編譯器「我是一個未經檢查的異常」,這是因爲編譯器知道RuntimeException類的全名並可以查找它們。 – 2013-02-14 16:42:37

1

事實上,它延伸RuntimeException就足夠了。在編譯期間,它知道類的層次結構是什麼,所以如果它包含RuntimeException,則它未被選中。否則,它會被檢查。請記住,checked/unchecked是一個編譯器約束,而不是運行時約束,有辦法讓Java拋出檢查從未被捕獲的異常。例如,使用Proxy

public class ExceptionalInvocationHandler implements InvocationHandler { 

    @Override 
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 
     throw new IOException("Take that, checked exceptions!"); 
    } 
} 

和接口:

public interface Example { 
    public void doSomething(); 
} 

,並創建一個代理,並調用它:

Example ex = (Example) Proxy.newProxyInstance(Example.class.getClassLoader(), 
    new Class[] { Example.class }, 
    new ExceptionalInvocationHandler()); 
ex.doSomething(); // Throws IOException even though it's not declared. 
+1

我知道它很簡單,但編譯器是如何知道它的? – 2013-02-14 16:24:06

+1

@DanielPereira因爲它構造了一個類層次結構?如果你想要確切的實施細節,這不是要問的地方。看看OpenJDK的編譯器源代碼。 – Brian 2013-02-14 16:25:44

+1

爲什麼Stackoverflow不是一個問這個問題的地方?我認爲這是一個編程問答網站。 – 2013-02-14 16:29:04

相關問題