捕获Java-8中的多个异常
在尝试我在捕获Java-8中的多个异常,java,exception,java-8,try-catch,Java,Exception,Java 8,Try Catch,在尝试我在m1()方法中找到的多捕获功能时,一切都正常 但是,在m2()中,不编译相同的代码。我刚刚更改了语法以减少代码行数 public class Main { public int m1(boolean bool) { try { if (bool) { throw new Excep1(); } throw new Excep2();
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()
不编译?表达式的类型
b ? new Excep1() : new Excep2()
是Exception
,因为这是Excep1
和Excep2
的常见超类型
但是,您没有捕获异常,因此编译器会对此进行投诉
如果捕获异常,它将通过编译:
public int m2(boolean b) {
try {
throw b ? new Excep1() : new Excep2();
} catch (Exception e) {
return 0;
}
}
我试图找到在您的示例中解释条件三元表达式类型的JLS条目
我所能找到的就是这个特殊的表达是一个
我不完全确定它是作为多边形表达式还是独立表达式。我认为它是独立的(因为poly表达式涉及赋值上下文或调用上下文,我不认为throw
语句算作这两者之一)
对于独立表达式:“如果第二个和第三个操作数具有相同的类型(可能是null类型),则这是条件表达式的类型。”
在您的情况下,第二个和第三个操作数有三种常见类型—对象
、可丢弃
和异常
——表达式的类型必须是后两种类型之一,因为“throw语句中的表达式必须表示可赋值的引用类型的变量或值(§5.2)到可丢弃的类型。”
编译器似乎选择了最具体的公共类型(Exception
),因此catch(Exception e)
解决了编译错误
我还尝试用两个子类
IOException
替换您的两个自定义异常,在这种情况下catch(IOException e)
解决了编译错误。您将编译器与以下行混淆:
throw b ? new Excep1() : new Excep2();
编译器看到表达式的结果(在抛出的右侧)是Except1和Except2之间的公共超类,它是Exception,因此要抛出的有效类型成为Exception。catch语句无法识别您试图抛出的异常1或异常2。Java限制您捕获或声明该方法可以抛出的所有异常类型 它搜索两个(/all)异常的公共父级,并期望您捕获或声明为抛出,例如,如果
Excep1
extendsThrowable
您还必须捕获Throwable
在第一种情况下,Java确定您正在抛出
EXEP1
或EXEP2
您得到了什么编译错误?@Smile三元条件表达式的类型必须对第二个和第三个操作数都是通用的。因此,它不能是Excep1
或Excep2
。它只能是异常
。15.25.3中的最后一个要点给出了答案:否则,第二个和第三个操作数分别为S1和S2类型。设T1为将装箱转换应用于S1时产生的类型,设T2为将装箱转换应用于S2时产生的类型。条件表达式的类型是将捕获转换(§5.1.10)应用于lub(T1,T2)的结果。“这里的lub是最小上界,这是两个表达式类型共享的最接近的公共超类型。