Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Catch exceptions which are not thrown locally?

Tags:

java

exception

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?

like image 439
bl3e Avatar asked May 22 '14 21:05

bl3e


People also ask

Can we catch exception without throw?

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.

Can we use catch () without passing arguments?

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.

What happens if a thrown exception is not caught anywhere in the program?

Explanation: When an exception is thrown and not caught, the program terminates abnormally.

What are the exceptions not handled by try-catch?

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.


Video Answer


1 Answers

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 or Exception or a superclass of Exception, 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 of C'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 of C's parameter is the same as or a subclass of the type of A'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:

  • An unchecked exception
  • Exception
  • Throwable (which is the only superclass of Exception other than Object, which you can't catch)
  • a checked exception that the try block can throw

The 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);
}
like image 107
yshavit Avatar answered Sep 22 '22 23:09

yshavit