2015-04-23 14 views
5

Warum ...Überprüfung Objektverweis Gleichheit == Verwendung (in Java)

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

... führen zu einer nicht kompatiblen Typen Fehler, wenn die gegebene Zusammenstellen ...

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

. .. nicht?

Warum kann ich die Objektreferenzen einer Zeichenfolge und eines Objekts, aber keinen StringBuilder und eine Zeichenfolge vergleichen? Sind das nicht alles nur Adressen an Speicherstellen?

Danke

+3

String ist 'Objekt' nicht' StringBuilder'. – Masudul

+0

Wäre es jemals möglich, dass 'String'- und' StringBuilder'-Referenzen dieselbe Instanz enthalten? Wenn nein, was ist der Sinn des 'a == b'-Tests? Wäre es nun möglich, dass 'Object'- und' StringBuilder'-Referenzen dieselben Instanzen enthalten? – Pshemo

Antwort

4

Acording auf die Java Language Specification (15.21.3):

Es ist ein Fehler bei der Kompilierung, wenn es unmöglich ist, wandle den Typ eines Operanden in den Typ des anderen Operanden um, indem du ihn umwandelst (§5.5). Die Laufzeitwerte der beiden Operanden wären notwendigerweise ungleich (wobei der Fall ignoriert wird, bei dem beide Werte Null sind).

Das bedeutet, um zwei Referenztypen zu "vergleichen", sollte man in der Lage sein, auf die andere zu übertragen. String "ist" ein Objekt, aber zwischen String und StringBuilder gibt es keinen "Cast".

+0

Ich werde in Zukunft auf die Spezifikation verweisen. Vielen Dank – Kayl669

3

Der Compiler versucht Ihnen zu helfen.

Wenn die == aufgrund widersprüchlicher Typen niemals wahr sein kann, wird davon ausgegangen, dass Sie einen Fehler gemacht haben und die Kompilierung des Codes ablehnen wird.

passiert mit instanceof auch, und auch mit Güssen.

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

String erweitert die Object Art, wie jede andere Klasse, ist aber nicht StringBuilder erben. Daher in Ihrem Vergleich String fällt zurück auf Object und sie haben einen Typ gemeinsam.

1

Da sowohl Strings als auch StringBuilder Kinder der Klasse Object sind. Sie sind jedoch nicht die gleiche Klasse, so dass sie nicht mit == verglichen werden können. Sie müssten die toString Methode auf StringBuilder aufrufen.

0

Im zweiten Beispiel String ist auch ein Objekt seit alle Klassen Unterklasse Objekt und Sie können überprüfen, ob sie == sind.

Im ersten Beispiel vergleichen Sie String mit StringBuilder, die unterschiedliche Klassen sind und keine der Unterklassen der anderen, so dass der Operator nicht funktioniert.

3

Da String ein Object ist aber String ist nicht StringBuilder. Sie können die Referenz mit == für denselben Typ und Supertyp vergleichen. Schauen Sie sich folgendes Beispiel

class A{ 

} 
class B extends A{ 

} 

class C{ 

} 

Jetzt

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 
+0

oder Bb = neu B(); wie der Fragesteller gerade gezeigt hat, ist dieser Kommentar falsch –

0

Da müssen Sie kompatible Typen vergleichen, da der Vergleich inkompatibler Typen für die Gleichheit immer false ist.

String ist kompatibel mit Object, daher ist das Vergleichen von Referenzen mit diesen Typen kein Kompilierungsfehler. StringBuilder ist kompatibel mit Object, so können Sie eine StringBuilder einer Object-typisierten Variable zuweisen. Aber String und StringBuilder sind nicht kompatibel mit einander. Wenn Sie also eine String Referenz und eine Object Referenz haben, können Sie sie ohne einen Kompilierungsfehler vergleichen. Aber wenn Sie eine String Referenz und eine StringBuilder Referenz haben, können Sie nicht   — der Compiler weiß, dass der Vergleich nie true sein wird.

Beachten Sie, wie es um den Typ der Referenzen (die Variablen) geht, nicht um den Typ der ihnen zugewiesenen Objekte. Deshalb ist es möglich, Ihr zweites Szenario einzurichten und es kompilieren zu lassen, obwohl es niemals ein echtes Ergebnis haben kann.

Verwandte Themen