Равенство сравнение "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".

Runnable версия на ideone.com

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 to Boolean и затем расширяющийся Boolean в Object) и затем сравнивается на равенство ссылок.

на EQUAL линия намного проще - все три случая являются вызовами Boolean.equals(Object other), используя бокс, когда аргумент three.