I'm testing some things about exception handling in Java 8. When a try-catch block is used, the catch
clauses are supposed to contain only exceptions that are thrown in the try
block.
Correct usage:
try {
throw new IOException();
} catch (IOException e){
// do something - this code will be activated
} catch (Exception e){
// do something - this code will not be activated
}
The IOException
catch clause matches the thrown exception in the try
block and will execute its code. If the IOException
catch clause becomes omitted, then the Exception
catch clause will activate because IOException
extends Exception
. This is very basic stuff. What I don't get is why the following code also compiles:
try {
throw new Exception();
} catch (IOException e){
// do something - this code will not be activated
} catch (Exception e){
// do something - this code will be activated
}
In this case, the most generic base-level exception is thrown. The thrown exception does not match IOException
and will be handled by the Exception
catch clause as a result. But I had expect the compiler to warn me that the IOException
catch clause is invalid because I neither throw it in the try
block nor do I call a method that throws an IOException
.
If I change the thrown exception to something that IOException
doesn't inherit from:
try {
throw new IllegalArgumentException();
} catch (IOException e){ // compiler complains about this line
} catch (Exception e){
}
then the compiler correctly tells me that the IOException is never thrown in the try
block and is thus invalid. Does this have something to do with an Exception
base class having the potential to contain an IOException
instance and having it match on that? Following that line of reasoning, does this mean that:
try {
Exception exception = new IOException();
throw exception;
}
will be caught by the IOException
catch clause?