可能已经分配了本地变量

时间:2015-05-27 10:17:49

标签: java javac

我知道有一些关于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如何初始化一个不知道的(因为它是一个局部变量,另一个线程不能干扰我的知识)。如果没有,为什么编译器会发出此警告?

6 个答案:

答案 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块和/或最后,这是有道理的。