My question is related to syntactic behavior of the try catch block
Empty try block with a catch as this
void fun() {
try {}
catch(Exception e) {}
}
or
try {}
catch(ArrayIndexOutOfBoundsException e) {}
compiles well but the compiler complains with
try {}
catch(IOException e) {}
Why does the compiler allow catching anything that is of type Exception or RuntimeException whereas it complains for unreachable code with checked exceptions? Is it because the JVM code can throw those types? How could the JVM possibly throw ArrayIndexOutOfBoundsException in an empty try block?
You can avoid catching an exception, but if there is an exception thrown and you don't catch it your program will cease execution (crash). There is no way to ignore an exception. If your app doesn't need to do anything in response to a given exception, then you would simply catch it, and then do nothing.
Some exception can not be catch(Exception) catched. Below excecption in mono on linux, should catch without parameter. Otherwise runtime will ignore catch(Exception) statment.
Explanation: When an exception is thrown and not caught, the program terminates abnormally.
When code reports an error, an exception cannot be caught if the thread has not yet entered a try-catch block. For example, syntaxError, because the syntax exception is reported in the syntax checking phase, the thread execution has not entered the try-catch code block, naturally cannot catch the exception.
The empty block is a special case which isn't specially handled by the JLS. What the JLS does require is that if you catch a checked exception, the code in the try
block must have been able to throw that exception (that is, it threw it directly or called a method that was declared to possibly throw it).
In other words, there's a sanity check specifically for checked exceptions, but not for all exceptions with checked exceptions getting extra consideration.
This is described in JLS 14.21, and specifically:
It is a compile-time error if a statement cannot be executed because it is unreachable.
...
A catch block
C
is reachable iff both of the following are true:
Either the type of
C
's parameter is an unchecked exception type orException
or a superclass ofException
, or some expression or throw statement in the try block is reachable and can throw a checked exception whose type is assignable to the type ofC
's parameter. (An expression is reachable iff the innermost statement containing it is reachable.)See §15.6 for normal and abrupt completion of expressions.
There is no earlier catch block
A
in the try statement such that the type ofC
's parameter is the same as or a subclass of the type ofA
's parameter.
Emphasis added: it shows that if you're catching an unchecked exception type, the catch block is reachable.
I personally find the wording a bit confusing. Slightly reworded, the first bullet point just says that the catch clause must catch one of:
Exception
Throwable
(which is the only superclass of Exception
other than Object
, which you can't catch)try
block can throwThe second bullet guards against a catch
block being unreachable because of a previous catch
in that try
. For instance:
try {
whatever();
} catch (Exception e) {
handleException(e);
} catch (NullPointerException e) {
// This block is unreachable, because a NullPointerException is an
// Exception and will thus be handled by the previous catch block.
handleNpe(e);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With