使用三元运算符抛出已检查或未检查的异常
Using Ternary Operator to Throw Checked or Unchecked Exceptions
我原来的问题使用了 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:
Unhandled exception type Exception
2 quick fixes available:
J!
Add throws declaration
J!
Surround with 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:
Unhandled exception type Throwable
2 quick fixes available:
J!
Add throws declaration
J!
Surround with try/catch
Why does this not compile?
因为条件运算符 ?: 的推断类型在这种情况下是 Exception
,遵循 JLS 15.25.3 的规则。虽然 JLS 变得非常复杂,但规则正在尝试找到 "the most specific type where there's an implicit conversion from both of the operand types"。一种 "nearest common ancestor".
本例中的继承层次为:
Exception
/ \
IOException RuntimeException
/ \
FileNotFoundException IllegalStateException
...所以最近的共同祖先是Exception
。您的代码有点等同于:
private void test() throws FileNotFoundException {
Exception exception = 1==0 ? new FileNotFoundException() : new IllegalStateException();
throw exception;
}
希望您已经明白为什么 that 会编译失败...如果幸运的话,现在一切都清楚了:)
我原来的问题使用了 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:
Unhandled exception type Exception
2 quick fixes available:
J!
Add throws declaration
J!
Surround with 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:
Unhandled exception type Throwable
2 quick fixes available:
J!
Add throws declaration
J!
Surround with try/catch
Why does this not compile?
因为条件运算符 ?: 的推断类型在这种情况下是 Exception
,遵循 JLS 15.25.3 的规则。虽然 JLS 变得非常复杂,但规则正在尝试找到 "the most specific type where there's an implicit conversion from both of the operand types"。一种 "nearest common ancestor".
本例中的继承层次为:
Exception
/ \
IOException RuntimeException
/ \
FileNotFoundException IllegalStateException
...所以最近的共同祖先是Exception
。您的代码有点等同于:
private void test() throws FileNotFoundException {
Exception exception = 1==0 ? new FileNotFoundException() : new IllegalStateException();
throw exception;
}
希望您已经明白为什么 that 会编译失败...如果幸运的话,现在一切都清楚了:)