我有一些代码:
final int var1;
if ( isSomethingTrue ) {
var1 = 123;
} else {
throwErrorMethod();
}
int var2 = var1;
throwErrorMethod定义如下:
private void throwErrorMethod() throws Exception{
throw new Exception();
}
我的blank final field may not have been initialized
语句出现var2 = var1
编译错误。如果我内联方法,编译就可以了!
throws Exception
may
的错误停止编译?!?答案 0 :(得分:19)
答案 1 :(得分:7)
例外应该是例外。它不会假设总是抛出异常。
编译器使用单词may
,因为它无法判断您是否可以访问未初始化的变量。此外,您可以更改该方法所执行的操作,而无需重新编译此类,并且所做的任何假设都是不正确的。
如果你想总是抛出一个异常,你可以做
final int var1;
if ( isSomethingTrue ) {
var1 = 123;
} else {
throw exceptionMethod();
}
int var2 = var1;
// later
public Exception exceptionMethod() {
return new Exception("Complex-Exception-String");
}
答案 2 :(得分:1)
编译器不会执行您期望的那种检查。它并不确定throwErrorMethod
每次实际上都会引发异常。因此,它假定您可以进入else
子句,调用throwErrorMethod
,从该方法返回,然后不初始化var1
(必须是初始化)。
答案 3 :(得分:1)
如果你想告诉编译器肯定会抛出错误,但又不想在构造错误的逻辑内联,你可以这样做:
} else {
throw createErrorMethod();
}
声明createErrorMethod()
返回某种Throwable。
答案 4 :(得分:0)
声明为“throws Exception”的方法不必在任何运行路径中抛出此异常。因此,编译器不知道该方法是否总是抛出异常并且也假定正常终止。因此,var1
可能未初始化。