为什么if(Boolean.TRUE){…}和if(TRUE){…}在Java中的工作方式不同

为什么if(Boolean.TRUE){…}和if(TRUE){…}在Java中的工作方式不同,java,boolean,Java,Boolean,我想知道if子句中Boolean.TRUE和TRUE值之间的区别。当我使用Boolean.TRUE而不是TRUE时,为什么它会给我一个编译错误(一个值可能尚未初始化) 下面是我的代码: public class Test { public void method1() { int x; if(Boolean.TRUE) { x = 200; } System.out.println("x: " +

我想知道
if
子句中
Boolean.TRUE
TRUE
值之间的区别。当我使用
Boolean.TRUE
而不是
TRUE
时,为什么它会给我一个编译错误(一个值可能尚未初始化)

下面是我的代码:

public class Test {

    public void method1() {
        int x;
        if(Boolean.TRUE) {
            x = 200;
        }
        System.out.println("x: " + x);   // Compilation error       
    }

    public void method2() {
        int x;
        if(true) {
            x = 200;
        }
        System.out.println("x: " + x);   // Compiles fine
    }
}

简短回答
对于
if(true)
编译器可以推断
x
在读取之前已经初始化。这不适用于
if(Boolean.TRUE)
情况

正式回答:
在读取()之前,所有局部变量必须有一个明确的赋值:

[…]如果声明符没有初始化表达式,则对变量的每次引用之前必须执行对变量的赋值,,否则根据§16的规则会发生编译时错误

在本例中,变量引用之前的代码中包含一个
if
语句,因此编译器执行一些流分析。然而,正如以下章节所述:

除了对条件布尔运算符
&&
|
的特殊处理外:
布尔值常量表达式中的,在流分析中不考虑表达式的值

因此,由于
true
是一个布尔值且
boolean.true
(它是对堆上的值的引用,受自动取消装箱等约束),因此

if (true) {
    x = 200;
}

if (Boolean.TRUE) {
    x = 200;
}

不会。

它确实抛出此错误,因为它不知道隐藏在布尔值后面的内容。TRUE
TRUE
是boolean类中boolean类型的静态字段,但其值也可以是
false
。不过,这并不明显。

之所以存在差异,是因为一个是真常数,而另一个只是模仿一个

编译器将查看类似于
if
语句的内容,并尝试确定它们是否始终是给定的表达式(
==true
==false
==null
,等等),但它只会在一定程度上执行此操作

true
的情况下,没有歧义:它总是毫无疑问地表示“true”。然而,
Boolean.TRUE
只是一个字段,这显然不是编译器愿意使用的范围

public static final Boolean TRUE = new Boolean(true);
例如,考虑一下如果涉及到反射,将会做什么

当引入额外的复杂性时,您可以清楚地看到这一点:

public static void main(String[] args) {
    int x;
    if(getCondition()) {
        x = 5;
    }
    System.out.println(x);
} 

private static boolean getCondition(){
    return true;
}

即使表达式始终为true,编译器仍会抱怨
x
可能未赋值。只有最基本的验证才能帮助您。

这毫无意义。检查真假有什么意义?@LawrenceAiello:你没有抓住问题的关键。在一种情况下,编译器可以正确识别表达式是否始终为真,而在另一种情况下则不能。它会抛出一个错误,即“值x可能尚未初始化”。这是因为在Boolean.TRUE后面还可以隐藏'false'。参见