Search code examples
javaexceptiontry-catchtry-catch-finally

Understanding Try/Finally Suppressed Exceptions


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.


Solution

  • 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.