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

Rav*_*ani 11 java boolean

我想知道子句内部Boolean.TRUEtrue值之间的区别if.当我使用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
    }
}
Run Code Online (Sandbox Code Playgroud)

aio*_*obe 10

简短的回答
对于if (true)编译器可以推断出x真实读取之前它已被初始化.这不适用于这种if (Boolean.TRUE)情况.

正式答案:
所有局部变量在读取之前必须具有明确的赋值(14.4.2.执行局部变量声明):

[...]如果声明者没有初始化表达式,那么每次对该变量的引用都必须先执行对该变量的赋值,否则会发生编译时错误,这是由§16的规则引起的.

在这种情况下,if在引用变量之前的代码中涉及一个语句,因此编译器执行一些流分析.但是,如第16章所述.确定任务:

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

如此以来,true是一个布尔值常量表达式Boolean.TRUE(这是一个值的引用在堆上,受自动拆箱等)它遵循

if (true) {
    x = 200;
}
Run Code Online (Sandbox Code Playgroud)

产生明确的xwhile 分配

if (Boolean.TRUE) {
    x = 200;
}
Run Code Online (Sandbox Code Playgroud)

才不是.


Jer*_*vel 5

存在差异是因为一个是真正的常数而另一个只是模仿一个.

编译器会看的东西像if语句和揣摩他们是否将永远是一个表达式(== true,== false,== null等),但它只会做这件事到一定水平.

true没有含糊不清的情况下:它总是无疑代表"真实".然而Boolean.TRUE,这只是一个字段,显然不是编译器愿意去的.

public static final Boolean TRUE = new Boolean(true);
Run Code Online (Sandbox Code Playgroud)

想一想如果涉及到反射会怎么做.

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

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

private static boolean getCondition(){
    return true;
}
Run Code Online (Sandbox Code Playgroud)

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