9

以下代码

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

使用 V1.7.0_15 编译没有错误javac,并在运行时打印“false”。但是,Eclipse Juno 抱怨“不兼容的操作数类型 Object 和 boolean”。

显然 javac 将原始 boolean自动装箱b,然后通过对象相等性进行比较o和自动装箱, yielding ,而 Eclipse 拒绝进行自动装箱。bfalse

根据 Java 语言规范,哪种行为是正确的?我应该在哪里提交错误?

注意:如果我将类型更改oBoolean,事情会按预期工作:Eclipse 接受代码,并且代码打印“true”。

ideone.com 上的可运​​行版本

4

2 回答 2

7

这是您的项目语言级别设置。您可能正在使用具有 Java 6 语义的 Java 7 编译器。我这里没有 Eclipse,但我在 IntelliJ 中复制了它,当语言级别为 Java 6 时它会出错,即使我使用的编译器是 7。我猜 Eclipse 也有。这个链接解释了它。

于 2013-05-27T09:56:40.180 回答
3

关于您的“注意”,代码在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比较 aBoolean和 an Object- 这些都是引用类型,所以测试是引用相等(Java Language Specification, Java SE 7 edition, §15.21.3
  • one == three将 aBoolean与 a进行比较boolean- 这被视为原始boolean值的比较(第 15.21.2 节);one已拆箱并与three.
  • two == three将 aObject与 a进行比较boolean- 在​​这种情况下,booleanObject通过强制转换(第 5.5 节,在这种情况下装箱booleanBoolean然后扩大BooleanObject)转换为,然后将两者进行比较以获得参考相等性。

EQUAL条线要简单得多——所有三种情况都是调用Boolean.equals(Object other),当参数是时使用装箱three

于 2013-05-27T11:13:50.740 回答