I have noticed that there are 2 kinds of checked exceptions:

1)

public static void main (String []args)
{
    try{
        //no exception thrown here, it still compiles though.
    }
    catch(Exception e){System.out.println(e);}
}

2)

public static void main (String []args)
{
    try{
         // it does not compile if not written any code which potentially might throw it
    }
    catch(IOException io){System.out.println(io);}
}

Is there any rule to anticipate this behaviour? to know in advance which is not mandatory to be present and it is? Hope I have been quite clear with explaining the issue. Thanks, Indeed ItIs

有帮助吗?

解决方案

The Java Language specification states

It is a compile-time error if a catch clause can catch checked exception class E1 and it is not the case that the try block corresponding to the catch clause can throw a checked exception class that is a subclass or superclass of E1, unless E1 is Exception or a superclass of Exception.

其他提示

The code compiles fine with Exception, because it is a super class of all Checked and Unchecked exceptions. So, a catch clause with Exception can handle the unchecked exception too. And for Unchecked exception, compiler cannot check at compile time that the exception is thrown or not. So, it won't give any error for Exception.

You can even try this with RuntimeException:

try {

} catch (RuntimeException e) {

}

... this will compile too.

From JLS Section 11.2.3 - Exception Checking:

It is a compile-time error if a catch clause can catch checked exception class E1 and it is not the case that the try block corresponding to the catch clause can throw a checked exception class that is a subclass or superclass of E1, unless E1 is Exception or a superclass of Exception.

Exception is a checked exception itself, but is also the superclass for RuntimeException and other unchecked exceptions.

1) In the first case, because the Exception class hierarchy includes RunTimeException, the compiler cannot conclude that an Exception will not be thrown in your try { ... } block. So, it must allow the code.

It can confirm the positive case (if you call a method that declares throws Exception or a non-run-time subclass), but it cannot confirm the negative case.

2) In the second case, it can conclude at compile-time that IOException will not be thrown in the try { ... } block, because IOException (nor any other checked exception besides Exception itself) is not the superclass for any run-time exceptions.


Of the following behaviors, I believe that Exception is the only special case with a combination of the two types:

If thrown:
1A. Does not need to be declared or 1B. Must be declared

If declared:
2A. Does not need to be thrown or 2B. Must be thrown

If not thrown:
3A. May be caught or 3B. Must not be caught

  • RuntimeException: 1A, 2A, 3A
  • Any other checked exception: 1B, 2B, 3B
  • Exception: 1B, 2A, 3A

More info on checked vs. unchecked exceptions in this answer: https://stackoverflow.com/a/6116020/143295

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top