我知道有一些关于stackoverflow的问题处理已经初始化的变量的问题,但我找不到任何回答我关于局部变量的问题。请考虑以下摘录:
public class Test {
public static void main() {
final int i;
try {
i = computeI();
} catch (Exception e) {
i = 5;
}
}
private static int computeI() throws Exception {
return 3;
}
}
java编译器(openjdk-8-jdk)告诉我i = 5
变量我可能已经初始化但是无法分配i
。
问题:有没有办法i
如何初始化一个不知道的(因为它是一个局部变量,另一个线程不能干扰我的知识)。如果没有,为什么编译器会发出此警告?
答案 0 :(得分:4)
Java编译器遵循Java语言规范。
您的问题由规范的以下部分回答:
https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.12.4
https://docs.oracle.com/javase/specs/jls/se7/html/jls-16.html#jls-16.2.15
基本上没有规则描述你捕获的异常类型和try块中的赋值位置。
还想象一下如果在try块中发生了一个错误(不会被catch异常捕获),那么在try语句之后仍然会取消分配i
。因此,即使编译器足够智能,也可以看到i
在catch块中未分配
它仍然需要抱怨未分配的最终变量。
答案 1 :(得分:1)
编译器并不像你想象的那么聪明。虽然你和我可以推断我只能在一个地方设置,但它并没有发现它,因此它看到的只是i的两个任务。
你可以使用临时变量解决它(如我对this post的回答)。
答案 2 :(得分:1)
不,无法分配变量。但是,编译器只有有限的演绎功能(显然它们在这种情况下失败),因此might
。
答案 3 :(得分:1)
在这种情况下,执行catch块时无法初始化i
变量,但编译器不够智能,无法理解,它没有发现它们之间的区别try块中的一个语句或多个语句。
无论如何,我更愿意使用一个简单的变量(不是常量)重写代码,并以这种方式将其分配给默认值:
int i = 5;
try {
i = computeI();
} catch (Exception e) {
//Exception handling
}
我的个人建议是: 永远不要使用try-catch代替if语句和标准控制流构造。
答案 4 :(得分:1)
由于您尝试分配的变量是最终的。在正常流的特定条件下,编译器不允许您将值分配给最终字段两次..但是如果您可以将其保持在条件内,则编译器是显示没有错误。
代表:
if(true) i = computeI(); 其他 i = 5;
答案 5 :(得分:-1)
当我们有多个catch块和/或最后,这是有道理的。