Java 爪哇语;空白的最终字段可能尚未初始化";方法oddness中引发异常
我有一些代码,比如:Java 爪哇语;空白的最终字段可能尚未初始化";方法oddness中引发异常,java,compiler-construction,compiler-errors,compiler-warnings,Java,Compiler Construction,Compiler Errors,Compiler Warnings,我有一些代码,比如: final int var1; if ( isSomethingTrue ) { var1 = 123; } else { throwErrorMethod(); } int var2 = var1; 投掷方法的定义如下: private void throwErrorMethod() throws Exception{ throw new Exception(); } 对于var2=var1语句,我得到一个空白的最终字段可能尚未初
final int var1;
if ( isSomethingTrue ) {
var1 = 123;
} else {
throwErrorMethod();
}
int var2 = var1;
投掷方法的定义如下:
private void throwErrorMethod() throws Exception{
throw new Exception();
}
对于var2=var1
语句,我得到一个空白的最终字段可能尚未初始化。如果我内联该方法,编译就可以了
编译器没有看到调用的方法上的抛出异常吗
为什么一个错误中有may
一词会停止编译李>
例外应该是例外。它并不假定总是抛出异常
编译器使用单词may
,因为它无法判断您是否可以访问未初始化的变量。此外,您可以在不重新编译该类的情况下更改该方法执行的操作,并且它所做的任何假设都是不正确的
如果希望始终抛出异常,可以这样做
final int var1;
if ( isSomethingTrue ) {
var1 = 123;
} else {
throw exceptionMethod();
}
int var2 = var1;
// later
public Exception exceptionMethod() {
return new Exception("Complex-Exception-String");
}
编译器不会执行您期望的那种检查。它不能确定throwErrorMethod
是否每次都实际抛出异常。因此,它假设可以进入else
子句,调用throwErrorMethod
,从该方法返回,然后不初始化var1
(必须初始化)
不,编译器不会确定throwErrorMethod
永远不会正常完成。规范中没有任何建议它应该这样做。不幸的是,没有办法表明方法永远不会正常返回
它只是“may”,因为存在一个潜在的执行路径,它不会初始化变量。这种执行路径的存在被定义为错误
你可能会发现Eric Lippert的这两篇博文(;)很有趣。这是关于C#而不是Java,但原理是一样的。声明为“抛出异常”的方法不必在任何运行路径中抛出此异常。因此,编译器不知道该方法是否总是抛出异常,并假定正常终止。因此,可能是var1
未初始化。如果您想告诉编译器肯定会抛出错误,但不想串联构造错误的逻辑,可以执行以下操作:
} else {
throw createErrorMethod();
}
其中createErrorMethod()
被声明为返回某种类型的可丢弃对象。不幸的是,没有办法表明方法永远不会正常返回。那真的很不幸吗?@马克:是的。如果您可以告诉编译程序强制执行它从未正常返回,然后稍后再使用该信息,则会使某些代码更清晰。。。比如这个问题中的代码。目前的规则很难将一段永远不会正常完成的代码提取到一个方法中,这仅仅是因为这种方式会影响确定的赋值。谢谢你的链接。好的,完成了,我看到了它的价值,谢谢。虽然我大部分时间都被公主新娘的介绍分散了注意力。