Home > Net >  Understanding Try/Finally Suppressed Exceptions
Understanding Try/Finally Suppressed Exceptions

Time:03-23

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.

  • Related