I'm learning Exceptions and I found out that you can have suppressed ones. I read many examples on stackoverflow but still, they don't work as they are supposed to in the "try/finally" case:
public class MultipleExceptionsExample {
static class IOManip implements Closeable{
@Override
public void close() {
throw new RuntimeException("from IOManip.close");
}
}
public static void main(String[] args) {
try(IOManip ioManip = new IOManip()){
throw new RuntimeException("from try!");
}catch(Exception e){
throw new RuntimeException("from catch!");
}finally{
throw new RuntimeException("from finally!");
}
}
}
As many explain, with all lines I should get: "java.lang.RuntimeException: from finally!" (Yes I do)
Removing finally block I should get: "java.lang.RuntimeException: from catch!" (Yes I do)
Removing catch block I should get:
Exception in thread "main" java.lang.RuntimeException: from try!
Suppressed: java.lang.RuntimeException: from IOManip.close
And I never do! Why? What am I missing?
By removing the catch block I should see the try message, but I get this instead:
Exception in thread "main" java.lang.RuntimeException: from finally!
at it.core.MultipleExceptionsExample.main(MultipleExceptionsExample.java:18)
Thanks a lot.
CodePudding user response:
A return or throw in a finally
block causes any other returned (or thrown) result to be ignored.
Don't return
or throw
in a finally
block, unless you really know what you're doing.
It should be noted that Java Throwables have a notion of "suppressed" exceptions: you can invoke addSuppressed
on a Throwable
that you have caught; this is done automatically with a try-with-resources block, if an exception occurs in the body and whilst closing the resource; but this does not happen for a throw in a finally
block.
CodePudding user response:
It is because finally
block would always execute. It doesn't matter if you catch the exception or not. To understand it better try the code bellow:
public static void main(String[] args) {
try (IOManip ioManip = new IOManip()) {
System.out.println("Try!");
throw new RuntimeException("from try!");
} finally {
System.out.println("Finally!");
}
}
Remember that it is not a good practice to return or throw from the finally block, and you should avoid doing that.