Java 局部变量可能已被赋值

Java 局部变量可能已被赋值,java,javac,Java,Javac,我知道stackoverflow中有几个问题是关于已经初始化的变量的问题,但是我找不到任何关于局部变量的问题的答案。考虑下面的摘录: public class Test { public static void main() { final int i; try { i = computeI(); } catch (Exception e) { i = 5; }

我知道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
中赋值


问题:有没有一种方法可以初始化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块!