Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Catching multiple exceptions in Java-8

While trying out the multi-catch feature I found in my m1() method everything is working fine as expected.

However, in m2() the same code does not compile. I have just changed the syntax to reduce the number of lines of code.

public class Main {      public int m1(boolean bool) {         try {             if (bool) {                 throw new Excep1();             }             throw new Excep2();             //This m1() is compiling  abs fine.         } catch (Excep1 | Excep2 e) {             return 0;         }     }      public int m2(boolean b) {         try {             throw b ? new Excep1() : new Excep2();             //This one is not compiling.         } catch (Excep1 | Excep2 e) {             return 0;         }     }      private static interface I {     }      private static class Excep1 extends Exception implements I {     }      private static class Excep2 extends Exception implements I {     } } 

Why doesn't method m2() compile?

like image 624
Sachin Sachdeva Avatar asked Jan 09 '20 11:01

Sachin Sachdeva


People also ask

Can I catch multiple exceptions java?

In Java SE 7 and later, we can now catch more than one type of exception in a single catch block. Each exception type that can be handled by the catch block is separated using a vertical bar or pipe | .

How do you handle multiple exceptions in catch block in java?

If a catch block handles multiple exceptions, you can separate them using a pipe (|) and in this case, exception parameter (ex) is final, so you can't change it. The byte code generated by this feature is smaller and reduce code redundancy.

How do you catch multiple exceptions in one catch?

Java allows you to catch multiple type exceptions in a single catch block. It was introduced in Java 7 and helps to optimize code. You can use vertical bar (|) to separate multiple exceptions in catch block.

Can we declare multiple exception in single catch block?

In Java SE 7 and later, a single catch block can handle more than one type of exception. This feature can reduce code duplication and lessen the temptation to catch an overly broad exception.


1 Answers

The type of the expression

b ? new Excep1() : new Excep2() 

is Exception, since that's the common supertype of Excep1 and Excep2.

However, you are not catching Exception, so the compiler complains about it.

If you catch Exception, it will pass compilation:

public int m2(boolean b) {     try {         throw b ? new Excep1() : new Excep2();     } catch (Exception e) {         return 0;     } } 

I tried to find the JLS entry that explains the type of conditional ternary expression in your example.

All I could find was that this particular expression is a 15.25.3. Reference Conditional Expression.

I'm not entirely sure if it counts as a poly expression or a standalone expression. I think it's standalone (since poly expressions involve an assignment context or an invocation context, and I don't think a throw statement counts as either of those).

For a standalone expression: "If the second and third operands have the same type (which may be the null type), then that is the type of the conditional expression."

In your case, the second and third operands have three common types - Object, Throwable and Exception - the type of the expression must be one of the latter two, since, "The Expression in a throw statement must either denote a variable or value of a reference type which is assignable (§5.2) to the type Throwable."

It appears that the compiler picks the most specific common type (Exception), and therefore a catch (Exception e) solves the compilation error.

I also tried to replace your two custom exceptions with two sub-classes of IOException, in which case catch (IOException e) solves the compilation error.

like image 77
Eran Avatar answered Sep 18 '22 15:09

Eran