使用三元运算符抛出已检查或未检查的异常

问题描述 投票:7回答:1

我的原始问题使用FileNotFoundExceptionIllegalStateException,因此它们包含在答案中。为简单起见,我已将它们分别更改为超类IOExceptionRuntimeException


这个编译(不使用三元,1个已选中,1个未选中):

private void test() throws IOException { // throws is required
    if (new Random().nextInt(2)==0) throw new IOException();
    throw new RuntimeException();
}

这也编译(使用三元,2个未经检查的例外):

private void test3() { // throws not required
    throw new Random().nextInt(2)==0 ? new UncheckedIOException(null) : new RuntimeException();
}

但为什么这不编译(使用三元,1检查,1未选中)?

private void test2() throws IOException {
    throw new Random().nextInt(2)==0 ? new IOException() : new RuntimeException();
}

来自Eclipse:

未处理的异常类型异常

2个快速修复:

J!添加投掷声明

J!环绕着try / catch


Another pair of examples

这编译:

private void test4() { // throws not required
    if (new Random().nextInt(2)==0) throw new Error();
    throw new RuntimeException();
}

这不是:

private void test5() {
    throw new Random().nextInt(2)==0 ? new Error() : new RuntimeException();
}

来自Eclipse:

未处理的异常类型Throwable

2个快速修复:

J!添加投掷声明

J!环绕着try / catch

java exception ternary-operator
1个回答
13
投票

为什么这不编译?

因为在这种情况下条件?:运算符的推断类型是Exception,遵循JLS 15.25.3的规则。虽然JLS很快变得复杂,但规则试图找到“最具体的类型,其中存在来自两种操作数类型的隐式转换”。一种“最近的共同祖先”。

在这种情况下,继承层次结构是:

                      Exception
                   /              \
           IOException           RuntimeException
               /                         \
      FileNotFoundException           IllegalStateException

...所以最近的共同祖先是Exception。您的代码有点等同于:

private void test() throws FileNotFoundException {
    Exception exception = 1==0 ? new FileNotFoundException() : new IllegalStateException();
    throw exception;
}

希望你已经明白为什么那会编译失败...在这种情况下如果运气好的话现在都清楚了:)

© www.soinside.com 2019 - 2024. All rights reserved.