Равенство сравнение "boolean" и "Object" разрешено?
следующий код
public class TestComparison {
public static void main(String[] args) throws Exception {
boolean b = true;
Object o = new Boolean(true);
System.out.println("comparison result: "+
(o == b)); // Eclipse complains about this expression
}
}
компилируется без ошибок с javac
V1.7.0_15, и печатает "false" при запуске. Однако Eclipse Juno жалуется на"несовместимые типы операндов Object и boolean".
по-видимому, javac autoboxes примитивный boolean b
, а затем сравнивает o
и autoboxed b
по равенству объектов, уступая false
, в то время как Eclipse отказывается делать автобоксинг.
которое правое поведение согласно Спецификация Языка Java? Где я должен подать ошибку?
Примечание: если я изменю тип o
to Boolean
, все работает так, как ожидалось: Eclipse принимает код, и код печатает "true".
2 ответов
это настройка уровня языка проекта. Вероятно, вы используете компилятор Java 7 с семантикой Java 6. У меня здесь нет Eclipse, но я воспроизвел его в IntelliJ, который дал ошибки, когда уровень языка был на Java 6, хотя компилятор, который я использовал, был 7. Я думаю, что Eclipse имеет то же самое. этой ссылке объясняет он.
относительно вашей "заметки", что код компилируется и работает, когда o
изменено на Boolean
:
этот код:
public class Tester{
public static void main(String args[]){
Boolean one = new Boolean(true);
Object two = new Boolean(true);
boolean three = true;
System.out.println("SAME 1:2 " + (one == two) + " 1:3 " + (one == three) + " 2:3 " + (two == three));
System.out.println("EQUAL 1:2 " + (one.equals(two)) + " 1:3 " + (one.equals(three)) + " 2:3 " + (two.equals(three)));
}
}
производит такой результат:
SAME 1:2 false 1:3 true 2:3 false
EQUAL 1:2 true 1:3 true 2:3 true
чтобы понять, почему это так, нам нужно рассмотреть времени компиляции типы различных выражений:
-
one == two
сравнитьBoolean
СObject
- это оба ссылочных типа, поэтому тест является ссылочным равенством (Язык Java Спецификация, Java SE 7 edition, §15.21.3) -
one == three
сравнитьBoolean
Сboolean
- это рассматривается как сравнение первобытногоboolean
значения (§15.21.2);one
распаковывается и сравнивается сthree
. -
two == three
сравниваетObject
Сboolean
- в этом случаеboolean
превращается вObject
путем преобразования литья (§5.5 в данном случае боксboolean
toBoolean
и затем расширяющийсяBoolean
вObject
) и затем сравнивается на равенство ссылок.
на EQUAL
линия намного проще - все три случая являются вызовами Boolean.equals(Object other)
, используя бокс, когда аргумент three
.