How does the Java compiler know that java.lang.RuntimeException and its subclasses are unchecked, since they inherit from java.lang.Exception, which is a checked exception? I looked into the code and doesn't seem to be anything inside the class that tells it to the compiler.
- Because it 'knows' what's written in the JLS, not just what's in the class hierarchy.user207421– user2074212013-02-15 03:59:17 +00:00Commented Feb 15, 2013 at 3:59
2 Answers
Because it is defined that way in the specification of the language # 11.1.1:
- The unchecked exception classes are the runtime exception classes and the error classes.
- The checked exception classes are all exception classes other than the unchecked exception classes. That is, the checked exception classes are all subclasses of Throwable other than RuntimeException and its subclasses and Error and its subclasses.
So it is not part of the code of the various exception classes, it is only a convention defined by the language, that compilers must implement to be compliant.
1 Comment
java.lang.RuntimeException is in use, and do whatever they need to do internally to flip from "checked" over to "unchecked". The source code doesn't get to tell the compiler "I'm an unchecked exception," it's that the compiler knows the full name of the RuntimeException class and can look for them.The fact that it extends RuntimeException is enough. During compile-time, it knows what the class hierarchy is, so if it includes RuntimeException, it's unchecked. Otherwise, it's checked. Remember that checked/unchecked is a compiler constraint, not a runtime constraint, there are ways to make Java throw checked exceptions that are never caught. For example, using 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!"); } } And an interface:
public interface Example { public void doSomething(); } And create a proxy and call it:
Example ex = (Example) Proxy.newProxyInstance(Example.class.getClassLoader(), new Class[] { Example.class }, new ExceptionalInvocationHandler()); ex.doSomething(); // Throws IOException even though it's not declared.