Java: Ganzzahl ist gleich vs. ==

Ab Java 1.5 können Sie Integer in vielen Situationen mit int austauschen.

Ich habe jedoch einen möglichen Defekt in meinem Code gefunden, der mich ein wenig überrascht hat.

Der folgende Code:

 Integer cdiCt = ...; Integer cdsCt = ...; ... if (cdiCt != null && cdsCt != null && cdiCt != cdsCt) mismatch = true; 

Es schien, als würde die falsche Übereinstimmung falsch eingestellt, wenn die Werte gleich waren, obwohl ich nicht bestimmen kann, unter welchen Umständen. Ich setzte einen Haltepunkt in Eclipse und sah, dass die Integer Werte beide 137 waren, und ich inspizierte den booleschen Ausdruck und es sagte, dass es falsch war, aber als ich darüber hinwegging, war es eine Nichtübereinstimmung zu wahren.

Ändern der Bedingung zu:

 if (cdiCt != null && cdsCt != null && !cdiCt.equals(cdsCt)) 

behebt das Problem.

Kann irgendjemand etwas darüber sagen, warum das passiert ist? Bisher habe ich das Verhalten auf meinem lokalen Host nur auf meinem eigenen PC gesehen. In diesem speziellen Fall hat der Code es erfolgreich über ungefähr 20 Vergleiche geschafft, aber am 2. fehlgeschlagen. Das Problem war konsistent reproduzierbar.

Wenn es ein vorherrschendes Problem ist, sollte es Fehler in unseren anderen Umgebungen (Entwicklung und Test) verursachen, aber bis jetzt hat niemand das Problem nach Hunderten von Tests gemeldet, die dieses Code-Snippet ausführen.

Ist es immer noch nicht legitim, == zu verwenden, um zwei Integer Werte zu vergleichen?

Zusätzlich zu all den feinen Antworten unten, hat der folgende Stackoverflow-Link eine Menge zusätzlicher Informationen. Eigentlich hätte es meine ursprüngliche Frage beantwortet, aber da ich Autoboxing in meiner Frage nicht erwähnte, tauchte es nicht in den ausgewählten Vorschlägen auf:

Warum kann der Compiler / JVM das Autoboxing nicht einfach “funktionieren” lassen?

Die JVM speichert Integer-Werte zwischen. == funktioniert nur für Zahlen zwischen -128 und 127 http://www.owasp.org/index.php/Java_gotchas#Immutable_Objects_.2F_Wrapper_Class_Caching

Sie können zwei Integer mit einem einfachen == Sie sind Objekte vergleichen, so dass die meisten Referenzen nicht identisch sind.

Es gibt einen Trick, mit Integer zwischen -128 und 127, Referenzen sind die gleichen wie Autoboxing verwendet Integer.valueOf() die kleine ganze Zahlen zwischengespeichert.

Wenn der Wert p, der eingerahmt wird, wahr, falsch, ein Byte, ein Zeichen im Bereich \ u0000 bis \ u007f oder eine int oder eine kurze Zahl zwischen -128 und 127 ist, dann seien r1 und r2 die Ergebnisse von zwei Box-Konvertierungen von p. Es ist immer der Fall, dass r1 == r2.


Ressourcen:

  • JLS – Boxen

Zum selben Thema:

  • Autoboxing vs manuelle Boxen Java

Das Problem ist, dass Ihre zwei Ganzzahl-Objekte genau das sind, Objekte. Sie stimmen nicht überein, weil Sie Ihre beiden Objektreferenzen und nicht die darin enthaltenen Werte vergleichen. Offensichtlich wird .equals außer Kraft gesetzt, um einen Wertevergleich im Gegensatz zu einem Objektreferenzvergleich bereitzustellen.

Integer bezieht sich auf die Referenz, Integer beim Vergleich von Referenzen, die Sie vergleichen, wenn sie auf dasselbe Objekt zeigen, nicht auf Wert. Daher das Problem, das Sie sehen. Der Grund, warum es so gut mit einfachen int Typen funktioniert, ist, dass es den Wert, der in Integer enthalten ist, auspackt.

Darf ich hinzufügen, dass, wenn Sie das tun, was Sie tun, warum sollte die if statement beginnen?

 mismatch = ( cdiCt != null && cdsCt != null && !cdiCt.equals( cdsCt ) ); 

“==” vergleichen Sie immer den Speicherort oder die Objektreferenzen der Werte. Gleich-Methode vergleichen Sie immer die Werte. Aber equals verwendet indirekt auch den Operator “==”, um die Werte zu vergleichen.

Integer verwendet Integer-Cache zum Speichern der Werte von -128 bis +127. Wenn der Operator == verwendet wird, um nach Werten zwischen -128 und 127 zu suchen, wird True zurückgegeben. Für andere als diese Werte gibt es false zurück.

Weitere Informationen finden Sie unter dem Link