首页 > 解决方案 > 在 Java-8 中捕获多个异常

问题描述

在尝试我在我的方法中发现的多捕获m1()功能时,一切都按预期正常工作。

但是,在m2()同一代码中无法编译。我刚刚更改了语法以减少代码行数。

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 {
    }
}

为什么方法不m2()编译?

标签: javaexceptionjava-8try-catch

解决方案


表达式的类型

b ? new Excep1() : new Excep2()

Exception,因为这是Excep1and的常见超类型Excep2

但是,您没有捕捉到Exception,因此编译器会抱怨它。

如果你 catch Exception,它将通过编译:

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

我试图在您的示例中找到解释条件三元表达式类型的 JLS 条目。

我所能找到的只是这个特定的表达式是15.25.3。参考条件表达式

我不完全确定它是否算作多边形表达式或独立表达式。我认为它是独立的(因为 poly 表达式涉及赋值上下文或调用上下文,我不认为throw语句算作其中任何一个)。

对于独立表达式:“如果第二个和第三个操作数具有相同的类型(可能是 null 类型),那么这就是条件表达式的类型。”

在您的情况下,第二个和第三个操作数具有三种常见类型 -ObjectThrowable-Exception表达式的类型必须是后两者之一,因为“throw 语句中的表达式必须表示变量或引用类型的值可分配(第 5.2 节)给 Throwable 类型。”

编译器似乎选择了最具体的常见类型 ( Exception),因此 acatch (Exception e)解决了编译错误。

我还尝试用 的两个子类替换您的两个自定义异常IOException,在这种情况下catch (IOException e)解决了编译错误。


推荐阅读