e is of type Exception but prints Exception1 in below code:
class Exception1 extends IOException {void info(){}}
class Exception2 extends Exception {}
class TestMultiCatch {
public static void main(String args[]) {
try {
int a = 10;
if (a <= 10)
throw new Exception1();
else
throw new Exception2();
} catch (Exception1 | Exception2 e) {
e.info(); //line 1 error "The method info() is undefined for type Exception"
System.out.println(e); //prints Exception1 (after commenting line 1)
}
}
}
From what I studied "e" should be of type Exception which is common base class of Exception1 and Exception2. Which it is, as evident from message in line 1.
But then why:
System.out.println(e); //prints Exception1 and not Exception
System.out.println(e instanceof IOException); //prints true and not false
System.out.println(e instanceof Exception1); //prints true and not false
System.out.println(e instanceof Exception2); //false
? Thanks.
When you use a multi-catch clause (the
Exception1 | Exception2 e
form ofcatch
), the compile-time type ofe
is the greatest type that the two types have in common, since of course the code has to handle either type of exception.From the spec:...where
lub
is Least Upper Bound as defined here.If you want to use anything that's specific to
Exception1
orException2
, use separatecatch
blocks:If
info
exists on bothException1
andException2
, refactor them so thatinfo
exists on a common ancestor class of them:...so the compiler can give
e
the typeTheAncestorException
and makeinfo
accessible.Here
e
is reference variable of both Exception1 and Exception2. So at compile timee.info();
will throw exception sinceinfo()
is not there forException2
.Better to use separate catch block for each since both classes don't have same method
info()
.The multi-catch seems to be your problem. You (the compiler) can only access methods which are defined on the common ancestors. Of course, "e" will be an Exception1 during runtime, but the compiler just cannot assume that, cause it could as well be an Exception2. Better create a catch block for both Exception1 and Exception2.