Почему if (Boolean.TRUE) {...} и if (true) {...} работают по-разному в Java
Я хочу знать разницу между значениями 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
}
}
Ответы
Ответ 1
Короткий ответ
Для if (true)
компилятор может вывести, что x
был инициализирован до его чтения. Это не выполняется для случая if (Boolean.TRUE)
.
Формальный ответ:
Все локальные переменные должны иметь определенное задание перед чтением (14.4.2. Выполнение локальных объявлений переменных):
[...] Если декларатор не имеет выражения инициализации, , то каждой ссылке на переменную должно предшествовать выполнение присваивания переменной, или возникает ошибка времени компиляции по правилам §16.
В этом случае существует оператор if
, связанный с кодом, предшествующим ссылке на переменную, поэтому компилятор выполняет некоторый анализ потока. Однако, как указано в Глава 16. Определенное назначение:
За исключением специальной обработки условных булевых операторов &&
, ||
и ? :
и булевых значений констант, значения выражений не учитываются в анализ потока.
Так как true
является булевозначным выражением и Boolean.TRUE
(которое является ссылкой на значение в куче, подлежит автоматическому распаковке и т.д.) не является, следует, что
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
. Однако это не очевидно.