使用==检查对象引用相等(在Java中)

时间:2015-04-23 09:58:17

标签: java

为什么......

    String a = new String("a");
    StringBuilder b = new StringBuilder("a");
    System.out.println(a==b);

...在编译时会导致类型不兼容的错误......

    String a = new String("b");
    Object b = new StringBuilder("b");
    System.out.println(a==b);

......不是吗?

为什么我可以比较String和Object的对象引用,但不能比较StringBuilder和String? Aren他们都只是在内存位置寻址吗?

由于

7 个答案:

答案 0 :(得分:4)

根据Java语言规范(15.21.3):

  

如果无法通过强制转换(§5.5)将任一操作数的类型转换为另一种操作数的类型,那么这是一个编译时错误。两个操作数的运行时值必然是不相等的(忽略两个值都为null的情况)。

这意味着,为了“比较”两种引用类型,应该能够将其转换为另一种引用类型。字符串“是”一个对象,但StringStringBuilder之间没有“强制转换”。

答案 1 :(得分:3)

编译器会尝试帮助您。

==由于类型冲突而永远不会成立时,它会假定您犯了一个错误,并拒绝编译代码。

同时发生instanceof,也发生演员表。

String a = null;
if (a instanceof StringBuilder){} // compile-error
StringBuilder b = (StringBuilder) a;  // compile-error

答案 2 :(得分:3)

因为,StringObject,但String不是StringBuilder。您可以使用相同类型和超类型的==来比较引用。请看下面的例子

class A{

}
class B extends A{

}

class C{

}

现在,

  A a =new A();
  A b =new B(); // or B b =new B();
  C c= new C();

  System.out.println(a==b); // It is ok
  System.out.println(a==c); // It will generate compile time error

答案 3 :(得分:2)

String扩展Object类型,与任何其他类一样,但不继承StringBuilder。因此,在您的比较中,String会回退到Object,而 共有类型。

答案 4 :(得分:1)

因为Strings和StringBuilders都是Object类的子类。但它们不是同一类,因此无法使用==进行比较。您需要在toString上调用StringBuilder方法。

答案 5 :(得分:0)

在第二个例子中,String也是一个Object,因为所有类都是Object的子类,你可以检查它们是否为==。

在第一个示例中,您将String与StringBuilder进行比较,它们是不同的类,并且都不是另一个的子类,因此运算符失败。

答案 6 :(得分:0)

因为您必须比较兼容类型,因为比较不兼容类型的相等性始终为false

StringObject兼容,因此将引用与这些类型进行比较不是编译时错误。 StringBuilderObject兼容,因此您可以将StringBuilder分配给Object类型的变量。但StringStringBuilder彼此不兼容。因此,如果您有String引用和Object引用,则可以在没有编译时错误的情况下对它们进行比较。但是如果你有一个String引用和一个StringBuilder引用,你就不能 - 编译器知道比较永远不会是true

注意所有关于引用类型(变量)的内容,而不是分配给它们的对象的类型。这就是为什么它可以设置你的第二个场景并让它编译,即使它永远不会有真正的结果。