Java编译器如何知道java.lang.RuntimeException
及其子类未被选中,因为它们是从java.lang.Exception
继承的,这是一个经过检查的异常?我查看了代码,似乎没有任何内容告诉编译器。
答案 0 :(得分:8)
因为它在specification of the language # 11.1.1:
中以这种方式定义
- 未经检查的异常类是运行时异常类和错误类。
- 已检查的异常类是除未经检查的异常类之外的所有异常类。也就是说,已检查的异常类都是Throwable的子类,而不是RuntimeException及其子类和Error及其子类。
因此,它不是各种异常类的代码的一部分,它只是由语言定义的约定,编译器必须实现这些约定。
答案 1 :(得分: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.