Java 局部变量可能已被赋值
我知道stackoverflow中有几个问题是关于已经初始化的变量的问题,但是我找不到任何关于局部变量的问题的答案。考虑下面的摘录:Java 局部变量可能已被赋值,java,javac,Java,Javac,我知道stackoverflow中有几个问题是关于已经初始化的变量的问题,但是我找不到任何关于局部变量的问题的答案。考虑下面的摘录: public class Test { public static void main() { final int i; try { i = computeI(); } catch (Exception e) { i = 5; }
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
中赋值
问题:有没有一种方法可以初始化a不知道的
i
(因为它是一个局部变量,另一个线程不能干扰我的知识)。如果没有,为什么编译器会发出此警告?编译器没有您想象的那么聪明。虽然你和我可以推断我可能只被安排在一个地方,但它没有发现这一点,因此它看到的只是给我的两个任务
您可以通过使用临时变量(如我对的回答中所述)绕过它。编译器没有您想象的那么聪明。虽然你和我可以推断我可能只被安排在一个地方,但它没有发现这一点,因此它看到的只是给我的两个任务
您可以通过使用临时变量(如我对的回答中所述)绕过它。不,无法分配该变量。但是,编译器只有有限的演绎功能(显然在这种情况下它们会失败),因此
可能会不,无法分配变量。然而,编译器只有有限的演绎功能(显然在这种情况下它们会失败),因此当我们有多个catch块时,可能会
,最后,这是有意义的 当我们有多个捕捉块和/或最终,这是有意义的 在这种情况下,执行catch块时,i
变量不可能被初始化,但编译器不够聪明,无法理解,它无法区分try块中的一条语句或多条语句
无论如何,我更愿意使用一个简单的变量(不是常数)重写代码,并在开始时以以下方式将其指定为默认值:
int i = 5;
try {
i = computeI();
} catch (Exception e) {
//Exception handling
}
我个人的建议是:千万不要用try-catch代替if语句和标准控制流结构。在这种情况下,执行catch块时,i
变量不可能被初始化,但编译器不够聪明,无法理解,它不区分try块中的一条语句或多条语句
无论如何,我更愿意使用一个简单的变量(不是常数)重写代码,并在开始时以以下方式将其指定为默认值:
int i = 5;
try {
i = computeI();
} catch (Exception e) {
//Exception handling
}
我个人的建议是:永远不要使用try-catch来代替if语句和标准控制流结构。Java编译器遵循Java语言规范
规范的以下部分回答了您的问题:
基本上,并没有规则描述捕获的异常类型和try块中的赋值位置
还可以想象一下,如果try块内发生错误(catch异常不会捕获),那么在try语句之后,i
仍将是未分配的。因此,即使编译器足够聪明,可以看到catch块中未分配i
它仍然需要抱怨未分配的最终变量。Java编译器遵循Java语言规范
规范的以下部分回答了您的问题:
基本上,并没有规则描述捕获的异常类型和try块中的赋值位置
还可以想象一下,如果try块内发生错误(catch异常不会捕获),那么在try语句之后,i
仍将是未分配的。因此,即使编译器足够聪明,可以看到catch块中未分配i
它仍然需要抱怨未分配的最终变量。因为您尝试分配的变量是最终变量。。在正常流的特定条件下,编译器将不允许您两次为最终字段赋值。。但若您能将其保持在一个条件内,编译器就不会显示任何错误
例如:
如果(真)
i=计算机();
其他的
i=5 因为您尝试分配的变量是最终变量。。在正常流的特定条件下,编译器将不允许您两次为最终字段赋值。。但若您能将其保持在一个条件内,编译器就不会显示任何错误
例如:
如果(真)
i=计算机();
其他的
i=5 因为静态
。这个问题有很多答案,这是说已经在i=computeI()中赋值了;因为这不是在初始化它时的最终结果。因为是静态的。这个问题有很多答案,这是说已经在i=computeI()中赋值了;因为这是最终的,不是你初始化它的时候。在多个catch块中,实际上只执行一个catch块!不可以。在多个catch块中,实际上只执行一个catch块!