1

当我这样做时,

if(a>=b && a>=c) {
    max = a;

} else if (b>=a && b>=c) {
    max = b;

} else if (c>=a && c>=b) {
    max = c;
}
System.out.println(max);

它给出了一个错误(java:变量 max 可能没有被初始化),但是当我这样做时,

if(a>=b && a>=c) {
    max = a;

} else if (b>=a && b>=c) {
    max = b;

} else {
    max = c;
}
System.out.println(max);

有用。为什么会这样?

4

6 回答 6

2

在第一种情况下,编译器所看到的只是您有 3 个条件语句为max. 因此,它认为存在一条可能的路径,其中没有一个条件为真,在这种情况下max不会被赋值。

您和我可以查看这些条件并理解其中一个必须是正确的。编译器不考虑这一点,它只是假设每个条件都可能为假。

else没有条件时,编译器可以保证至少有一个分配将执行。因此没有错误。

于 2021-09-01T13:48:32.070 回答
0

你的问题的答案很简单。当 if 语句不真实时,总是会运行 else。您的 IDE 抱怨 max 可能未初始化,因为它实际上并不理解代码。为避免它,您可以执行以下操作:

    int max = 0;
    if(a>=b && a>=c) {
        max = a;

    } else if (b>=a && b>=c) {
        max = b;

    } else if (c>=a && c>=b) {
        max = c;

    }
    System.out.println(max);
于 2021-09-01T13:46:36.417 回答
0

在 else if 中,条件是必须的。只有当条件满足时它才会进入。在第一种情况下,如果所有条件都为假,那么 max 将保持未初始化,而在第二种情况下,如果 if 和 else if 条件都为假,则 else 部分肯定会执行。因此 max 在所有场景中肯定会有一些价值。

于 2021-09-01T13:49:37.277 回答
0

在您的第一个示例中,Java 不确定是否执行了 if/else 块。因此,如果您 p​​rint out max,它可能仍然为空。在您的第二个示例中,无论变量max将具有值(c),如果不是在它上面的 if/else 链中确定的其他值。这也取决于您如何初始化max. 例如,如果你max这样声明

 int max;

 if(a>=b && a>=c) {
     max = a;

 } else if (b>=a && b>=c) {
     max = b;

 } else if (c>=a && c>=b) {
     max = c;
 }
 System.out.println(max);

max从来没有被赋值,所以它是空的。如果您改为实例化它

 int max = 0;

 if(a>=b && a>=c) {
     max = a;

 } else if (b>=a && b>=c) {
     max = b;

 } else if (c>=a && c>=b) {
     max = c;
 }
 System.out.println(max);

即使 max 在 if/else 链中没有改变,它仍然有一个值要打印。

于 2021-09-01T13:54:07.007 回答
0

我假设您的变量声明如下所示:

int a = 0;
int b = 0;
int c = 0;
int max;

并且在 System.out.println(max) 中调用 max 时会发生变量未初始化错误,最重要的区别在于这部分:#1

} else {
   max = c;
} 

#2

} else if (c>=a && c>=b) {
   max = c;
}

因此,对于案例#1 ,编译器 100% 确定即使您没有陷入任何先前的 if 条件 ((a>=b && a>=c) (b>=a && b>=c)) ,您将最终进入一个 else 块,它将处理其余的情况。但是,对于案例#2,您的 if 树的最后一部分仍然是一个条件。并且编译器假设有一种可能性,即 (a>=b && a>=c)、(b>=a && b>=c) 和 (c>=a && c>=b) 都不是真的,因此,认为 max 未初始化。

于 2021-09-01T13:56:29.233 回答
0

简而言之:那里的else声明的存在保证了它max的设置。

编译器应用流分析来检查是否明确分配了局部变量,并且编译器足够聪明1可以检测到在max使用之前设置了所有可能的代码路径。

这在Java 语言规范的第 16 章中有详细定义。


1正如 Feuermurmel 在评论中已经说过的,编译器不会分析条件表达式。从逻辑上讲,其中一个条件必须为真,我们人类肯定知道。但是对编译器的这种分析不会达到那么远,可能是为了降低复杂性。

于 2021-09-01T13:58:07.203 回答