我的原始问题使用FileNotFoundException
和IllegalStateException
,因此它们包含在答案中。为简单起见,我已将它们分别更改为超类IOException
和RuntimeException
。
这个编译(不使用三元,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
这编译:
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
为什么这不编译?
因为在这种情况下条件?:运算符的推断类型是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;
}
希望你已经明白为什么那会编译失败...在这种情况下如果运气好的话现在都清楚了:)