reference type of exception issue in multi-catch block

主宰稳场 提交于 2019-12-02 01:52:14

When you use a multi-catch clause (the Exception1 | Exception2 e form of catch), the compile-time type of e 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:

An exception parameter may denote its type as either a single class type or a union of two or more class types (called alternatives). The alternatives of a union are syntactically separated by |.

A catch clause whose exception parameter is denoted as a single class type is called a uni-catch clause.

A catch clause whose exception parameter is denoted as a union of types is called a multi-catch clause.

...

The declared type of an exception parameter that denotes its type as a union with alternatives D1 | D2 | ... | Dn is lub(D1, D2, ..., Dn).

...where lub is Least Upper Bound as defined here.

If you want to use anything that's specific to Exception1 or Exception2, use separate catch blocks:

} catch (Exception1 e) {
    // Something using features of Exception1
} catch (Exception2 e) {
    // Something using features of Exception2
}

If info exists on both Exception1 and Exception2, refactor them so that info exists on a common ancestor class of them:

class TheAncestorException extends Exception {
    public void info() { // Or possibly make it abstract
        // ...
    }
}
class Exception1 extends TheAncestorException {
    // Optionally override `info` here
}
class Exception2 extends TheAncestorException {
    // Optionally override `info` here
}

...so the compiler can give e the type TheAncestorException and make info accessible.

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.

catch (Exception1 | Exception2 e) {....}

Here e is reference variable of both Exception1 and Exception2. So at compile time e.info(); will throw exception since info() is not there for Exception2.

Better to use separate catch block for each since both classes don't have same method info().

} catch (Exception1 e) {
            e.info();  
            System.out.println(e);  
        } catch (Exception2 e) {
            System.out.println(e);
        }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!