【问题标题】:Why does if(Boolean.TRUE) {...} and if(true) {...} work differently in Java为什么 if(Boolean.TRUE) {...} 和 if(true) {...} 在 Java 中的工作方式不同
【发布时间】:2015-02-16 16:47:11
【问题描述】:

我想知道if 子句中Boolean.TRUEtrue 值之间的区别。当我使用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
    }
}

【问题讨论】:

  • 这毫无意义。检查 true 是否为 true 有什么意义?
  • @LawrenceAiello:你错过了问题的重点。在一种情况下,编译器可以正确识别表达式始终为真,在另一种情况下则不能。
  • 它会抛出一个错误,但那是“值 x 可能尚未初始化”。那是因为在 Boolean.TRUE 后面也可以隐藏“false”。

标签: java boolean


【解决方案1】:

简答
对于if (true),编译器可以推断出x 在被读取之前已经被初始化。这不适用于if (Boolean.TRUE) 案例。

正式回答:
所有局部变量在被读取之前必须有一个明确的赋值 (14.4.2. Execution of Local Variable Declarations):

[...] 如果声明器没有初始化表达式,那么每次对变量的引用都必须先执行对变量的赋值,否则会发生编译时错误根据第 16 条的规则。

在这种情况下,在引用变量之前的代码中涉及if 语句,因此编译器会执行一些流分析。但是,正如Chapter 16. Definite Assignment 中所述:

除了条件布尔运算符&&||? :以及布尔值常量表达式的特殊处理之外,表达式的值在流量分析。

因此,由于 true 是布尔值 constant expressionBoolean.TRUE(它是对堆上的值的引用,受自动拆箱等影响)is not,因此

if (true) {
    x = 200;
}

产生x 的明确分配,而

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

没有。

【讨论】:

    【解决方案2】:

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

    编译器将查看 if 语句之类的内容,并尝试确定它们是否始终是给定的表达式(== true== false== null 等),但它只会这样做一定程度。

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

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

    【讨论】:

      【解决方案3】:

      它确实抛出了这个错误,因为它不知道隐藏在Boolean.TRUE 后面的是什么。 TRUE 是 Boolean 类中 boolean 类型的静态字段,但它的值也可以是 false。 '虽然不是很明显。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-06-21
        • 2013-08-10
        • 1970-01-01
        • 2014-12-02
        • 1970-01-01
        • 2013-05-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多