我想知道Boolean.TRUE
子句中true
和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
}
}
答案 0 :(得分:10)
简短回答
对于if (true)
,编译器可以推断出x
在被读取之前已被初始化。这不适用于if (Boolean.TRUE)
案例。
正式回答:
在阅读(14.4.2. Execution of Local Variable Declarations)之前,所有局部变量必须具有明确赋值:
[...]如果声明者没有初始化表达式那么每次对变量的引用都必须先执行对变量的赋值,否则会发生编译时错误根据§16的规则。
在这种情况下,在引用变量之前的代码中涉及if
语句,因此编译器会执行一些流分析。但是,如Chapter 16. Definite Assignment中所述:
除了条件布尔运算符
&&
,||
和? :
以及布尔值常量表达式的特殊处理外,表达式的值在流量分析中不考虑。
因为true
是一个布尔值constant expression和Boolean.TRUE
(它是对堆上值的引用,需要自动取消装箱等)is not它遵循
if (true) {
x = 200;
}
在
时产生x
的明确赋值
if (Boolean.TRUE) {
x = 200;
}
没有。
答案 1 :(得分:5)
存在差异是因为一个是真正的常数而另一个只是模仿一个。
编译器将查看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
可能未被分配。只有最基本的验证才能帮助您。
答案 2 :(得分:1)
它确实会抛出此错误,因为它不知道Boolean.TRUE
背后隐藏着什么。 TRUE
是布尔类中布尔类型的静态字段,但其值也可以是false
。但事实并非如此。