首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Java-8中捕获多个异常

在Java-8中捕获多个异常
EN

Stack Overflow用户
提问于 2020-01-09 11:10:51
回答 3查看 6.9K关注 0票数 70

在尝试在我的m1()方法中发现的多捕获特性时,一切都如预期的那样正常工作。

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

代码语言:javascript
复制
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()不编译?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-01-09 11:14:02

表达式的类型

代码语言:javascript
复制
b ? new Excep1() : new Excep2()

Exception,因为这是Excep1Excep2的常见超级类型。

但是,您没有捕获Exception,所以编译器会抱怨它。

如果捕获Exception,它将通过编译:

代码语言:javascript
复制
public int m2(boolean b) {
    try {
        throw b ? new Excep1() : new Excep2();
    } catch (Exception e) {
        return 0;
    }
}

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

我所能找到的就是这个特殊的表达式是一个15.25.3。参考条件表达式

我不完全确定它是一个复合表达式还是一个独立表达式。我认为它是独立的(因为多表达式涉及赋值上下文或调用上下文,而且我不认为throw语句就是其中之一)。

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

在您的示例中,第二个和第三个操作数有三种常见类型-- ObjectThrowableException --表达式的类型必须是后两种类型之一,因为“抛出语句中的表达式必须表示可分配给类型Throwable的引用类型的变量或值(§5.2)”。

编译器似乎选择了最特定的公共类型(Exception),因此catch (Exception e)解决了编译错误。

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

票数 81
EN

Stack Overflow用户

发布于 2020-01-09 11:19:56

您将编译器与这一行混淆在一起:

代码语言:javascript
复制
throw b ? new Excep1() : new Excep2();

编译器看到表达式的结果(抛出的右边)是Except1和Except2之间常见的超类,这是异常,因此抛出的有效类型变成异常。catch语句无法获取您试图抛出的Excep1或Except2。

票数 23
EN

Stack Overflow用户

发布于 2020-01-09 11:20:27

Java限制您捕获或声明方法可以抛出的所有异常类型,

它搜索两个(/all)异常的公共父级,并期望您捕获或声明为抛出,例如,如果Excep1扩展了Throwable,那么您也必须捕获Throwable。

在第一种情况下,Java确信您正在抛出Excep1Excep2

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59662659

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档