2009-10-18 3 views

Antwort

2

Bei Referenztypen vergleicht == die tatsächliche Referenz (wo sich das Objekt im Speicher befindet), wo die Methode equals einen Vergleich der Daten durchführt.

Die JVM wird Ihre unveränderlichen Zeichenfolgen aus Leistungsgründen manchmal "String intern" zuweisen. diese Verursachung:

String a = "abc"; 
String b = "abc"; 
if (a == b){ 
    //The if statement will evaluate to true, 
    //if your JVM string interns a and b, 
    //otherwise, it evaluates to false. 
} 

http://en.wikipedia.org/wiki/String_interning

+0

ein neues Konzept gelernt - Internierung! – lft93ryt

1

Die ‚==‘ Operator auf dem Urtyp arbeitet Sie, dass im Falle von Referenzobjekten haben, ist die Referenz selbst. Das heißt, a == b vergleicht die Werte für primitive Typen als int, vergleicht aber die Referenz (nicht den Wert) für Referenztypen. Zwei Objekte des Referenztyps, die nicht identisch sind, aber denselben Wert haben, geben true zurück, wenn die Methode equals() aufgerufen wird, aber a == b wird falsch sein.

Bei primitiven Typen wird der Typ beim Aufrufen einer Methode zuvor in einen Referenztyp konvertiert (eingerahmt) und anschließend die Methode aufgerufen. Dies bedeutet, dass für primitive Typen a == b den gleichen Wert wie a.equals(b) ergibt. Im letzteren Fall werden jedoch vor dem Aufruf der Methode equals() zwei temporäre Box-Objekte erstellt. Dadurch wird die Operation in der CPU-Zeit teurer, je nachdem, wo sie stattfindet.

Das heißt, um primitive Typenwerte zu vergleichen, sollten Sie == verwenden, während beim Vergleich von Referenztypwerten die Methode .equals() verwendet werden sollte.

Das gleiche passiert mit der toString() Methode. Wenn ein Objekt vom Referenztyp aufgerufen wird, ruft es die entsprechende Methode auf und erzeugt einen String. Wenn ein primitiver Typ aufgerufen wird, wird der Typ autoboxiert und dann wird die Methode im temporären Objekt aufgerufen. In diesem Fall können Sie die entsprechende statische Methode toString() (d. H. Für Int-Aufruf Integer.toString(myint)) aufrufen, damit das temporäre Objekt nicht erstellt wird.

+0

'a.equals (b)' wird nicht kompiliert, wenn 'a' ein primitiver Typ ist. – ajb

7

Für regelmäßige Typen (einschließlich String):

  • == vergleicht Objektreferenzen. Es testet, ob zwei Objektreferenzen gleich sind; wenn sie sich auf das gleiche Objekt beziehen.
  • equals(Object) testet, ob dieses Objekt einem anderen "gleich" ist. Was "gleich" bedeutet, hängt davon ab, wie die Klasse des Objekts Gleichheit definiert. Die Klasse java.lang.Object definiert equals(other) als this == other, aber viele Klassen überschreiben diese Definition.
  • toString() bietet eine einfache Umwandlung des Objekts in einen String. Das Format und der Inhalt des resultierenden Strings ist klassenspezifisch und (aus der Sicht des java.lang.Object Vertrags) gibt es keine Garantie, dass es sinnvoll ist.

Für (true) Urtyp:

  • == Werte des Typs vergleicht, und
  • equals()toString() und sind nicht definiert. Java erlaubt Ihnen nicht, eine Methode für einen primitiven Wert aufzurufen.

jedoch dies durch die Tatsache, dass in manchen Kontexten ist kompliziert die Java-Sprache sagt, dass ein primitiver Typ kann „autoboxed“ werden, um eine Instanz der Urtyp des entsprechenden Wrapper-Typ zu geben; z.B. int entspricht java.lang.Integer und so weiter. Für die Wrapperklassen:

  • == ist die gleiche wie für jeden anderen Referenztyp definiert,
  • equals() der umhüllten Werte vergleicht und
  • toString() formatiert die Werte gewickelt.

Der Schlüssel in den Arbeiten wird durch den folgenden veranschaulicht:

int a = ... 
int b = a; 
Integer aa = a;  // autoboxing occurs 
Integer bb = b;  // autoboxing occurs 

assert a == b;   // always succeeds 
assert aa.equals(bb); // always succeeds 
assert aa == bb;  // sometimes succeeds, sometimes fails. 

Der Grund, dass die letzten manchmal versagt ist, dass die JLS garantiert nicht, dass ein gegebenen Grundwert Autoboxing immer die gleiche Wrapper geben Objekt. Es wird in einigen Fällen (z. B. für kleine ganze Zahlen) und nicht für andere (z. B. große ganze Zahlen).

Die Lehre aus dem obigen Beispiel gelernt wird, ist, dass Sie über die Verwendung == auf einem Referenz-Typ sehr vorsichtig sein müssen. Verwenden Sie es nur, wenn Sie wirklich möchten, wenn zwei Referenzen auf das gleiche Objekt sind. Verwenden Sie es nicht, wenn Sie wollen einfach zu testen, ob die Objekte ohne den Overhead Aufruf equals() „gleich“ sind.

(Beachten Sie auch, dass String ein anderer Typ ist, wo == Sie die falsche Antwort in vielen Situationen wird geben, siehe How do I compare strings in Java?.)

+0

'==' on primitives überprüft nur die Werte und ignoriert die Typen. 'int x = 5; lange y = 5L; Byte b = 5; x == y; b == x; 'Beide kehren wahr zurück. – arun

+1

Es "ignoriert" die Typen nicht. Die eine oder andere der Operanden wird an die Art des anderen gefördert. Außerdem habe ich "Werte des Typs" gesagt ... –

Verwandte Themen