简体   繁体   English

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

[英]Why does if(Boolean.TRUE) {…} and if(true) {…} work differently in Java

I want to know the difference between Boolean.TRUE and true values inside an if clause. 我想知道if子句中Boolean.TRUEtrue值之间的区别。 Why does it give me a compilation error (that a value may not have been initialized) when I use Boolean.TRUE instead of true . 当我使用Boolean.TRUE而不是true时,为什么它会给我一个编译错误(一个值可能没有被初始化)。

Below is my code : 以下是我的代码:

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
    }
}

Short answer 简短的回答
For if (true) the compiler can deduce that x has been initialized before it's being read. 对于if (true) ,编译器可以推断出x在被读取之前已被初始化。 This does not hold for the if (Boolean.TRUE) case. 这不适用于if (Boolean.TRUE)情况。

Formal answer: 正式答案:
All local variables must have a definite assignment before being read ( 14.4.2. Execution of Local Variable Declarations ): 在读取之前,所有局部变量必须具有明确的赋值14.4.2。执行局部变量声明 ):

[...] If a declarator does not have an initialization expression, then every reference to the variable must be preceded by execution of an assignment to the variable , or a compile-time error occurs by the rules of §16. [...]如果声明者没有初始化表达式, 那么每次对该变量的引用都必须先执行对该变量的赋值 ,否则会发生编译时错误,这是由§16的规则引起的。

In this case there's an if statement involved in the code preceding the reference to the variable, so the compiler performs some flow analysis. 在这种情况下,在变量引用之前的代码中涉及if语句,因此编译器执行一些流分析。 However, as spelled out in Chapter 16. Definite Assignment : 但是,如第16章所述。确定任务

Except for the special treatment of the conditional boolean operators && , || 除了条件布尔运算符&&||的特殊处理 , and ? : ,和? : ? : and of boolean-valued constant expressions , the values of expressions are not taken into account in the flow analysis. ? :布尔值常量表达式一样 ,在流分析中不考虑表达式的值。

So since true is a boolean-valued constant expression and Boolean.TRUE (which is a reference to a value on the heap, subject to auto-unboxing etc) is not it follows that 所以,因为true是一个布尔值的常量表达式,Boolean.TRUE (它是对堆上的值的引用,受自动拆箱等影响) 是不是遵循

if (true) {
    x = 200;
}

yields a definite assignment of x while 产生x的明确分配

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

does not. 才不是。

The difference exists because one is a true constant while the other is just mimicking one. 存在差异是因为一个是真正的常数而另一个只是模仿一个。

The compiler will look at things like if statements and try to figure out whether they will always be a given expression ( == true , == false , == null , etc) but it will only do this up to a certain level. 编译器将查看if语句之类的内容并尝试确定它们是否始终是给定的表达式( == true== false== null等),但它只会达到某个级别。

In the case of true there is no ambiguity: it will always undoubtedly represent "true". true的情况下,没有歧义:它总是无疑代表“真实”。 However Boolean.TRUE is just a field, which is apparently not as far as the compiler is willing to go. 但是, Boolean.TRUE只是一个字段,显然不是编译器愿意去的那个字段。

public static final Boolean TRUE = new Boolean(true);

Think for example about what would be done if reflection is involved. 想一想如果涉及到反射会怎么做。

You can see this clearly when you introduce an extra level of complexity: 当您引入额外的复杂性时,您可以清楚地看到这一点:

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

private static boolean getCondition(){
    return true;
}

Even though the expression will always be true, the compiler still complains that x might be unassigned. 即使表达式始终为true,编译器仍会抱怨x可能未被赋值。 Only the most rudimentary verification is done to help you. 只有最基本的验证才能帮助您。

It does throw this error because it does not know what hides behind Boolean.TRUE . 它确实抛出了这个错误,因为它不知道隐藏在Boolean.TRUE背后的是什么。 TRUE is a static field of the type boolean in the class Boolean, but its value could also be false . TRUE是布尔类中布尔类型的静态字段,但其值也可能为false It isn't obviously, 'though. 但事实并非如此。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM