TL; DR
Java zwischenspeichert Boxed Integer-Instanzen von -128
bis 127
. Da Sie verwenden ==
Objekte vergleichen Referenzen statt Werte werden nur im Cache gespeicherten Objekte entsprechen. Arbeiten long
Sie entweder mit primitiven Werten ohne Box oder .equals()
vergleichen Sie Ihre Long
Objekte.
Lange (Wortspiel beabsichtigt) Version
Warum ist es problematisch, die Variable Long mit einem Wert größer als 127 zu vergleichen? Wenn der Datentyp der obigen Variablen primitiv (lang) ist, funktioniert der Code für alle Werte.
Java speichert Instanzen von Integer-Objekten im Bereich von -128 bis 127 zwischen . Das gesagt:
- Wenn Sie den Wert
127
( zwischengespeichert ) auf N Long-Variablen setzen , wird dieselbe Objektinstanz von allen Referenzen angezeigt. (N Variablen, 1 Instanz)
- Wenn Sie den Wert
128
( nicht zwischengespeichert ) auf N Long-Variablen setzen , wird von jeder Referenz eine Objektinstanz angezeigt. (N Variablen, N Instanzen)
Deshalb das:
Long val1 = 127L;
Long val2 = 127L;
System.out.println(val1 == val2);
Long val3 = 128L;
Long val4 = 128L;
System.out.println(val3 == val4);
Gibt dies aus:
wahr
falsch falsch
Für den 127L- Wert wird zurückgegeben, da beide Referenzen (val1 und val2) auf dieselbe Objektinstanz im Speicher verweisen (zwischengespeichert) true
.
Auf der anderen Seite wird für den 128- Wert, da keine Instanz für ihn im Speicher zwischengespeichert ist, eine neue für alle neuen Zuweisungen für Box-Werte erstellt, was zu zwei verschiedenen Instanzen führt (auf die durch val3 und val4 gezeigt wird) und false
auf den Wert zurückkehrt Vergleich zwischen ihnen.
Dies geschieht nur, weil Sie zwei Long
Objektreferenzen und keine long
primitiven Werte mit dem ==
Operator vergleichen. Ohne diesen Cache-Mechanismus würden diese Vergleiche immer fehlschlagen. Das eigentliche Problem hierbei ist also der Vergleich von Boxwerten mit dem ==
Operator.
Das Ändern dieser Variablen in primitive long
Typen verhindert dies. Wenn Sie Ihren Code jedoch mithilfe von Long
Objekten beibehalten müssen, können Sie diese Vergleiche sicher mit den folgenden Ansätzen durchführen:
System.out.println(val3.equals(val4)); // true
System.out.println(val3.longValue() == val4.longValue()); // true
System.out.println((long)val3 == (long)val4); // true
(Eine ordnungsgemäße Nullprüfung ist auch für Gussteile erforderlich.)
IMO , es ist immer eine gute Idee, sich bei Objektvergleichen an die Methoden .equals () zu halten .
Referenzlinks:
.longValue()
.Beim Vergleich von Nicht-Grundelementen (auch als Objekte bezeichnet) in Java wird
==
deren Referenz anstelle ihrer Werte verglichen.Long
ist eine Klasse und somit sindLong
Werte Objekte.Das Problem ist, dass die Java-Entwickler wollten , dass die Benutzer die Kompatibilität
Long
wie früher verwendenlong
, was zu dem Konzept des Autoboxing führte, bei dem es sich im Wesentlichen um die Funktion handelt, dasslong
-Werte nach Bedarf inLong
-Objects geändert werden und umgekehrt. Das Verhalten von Autoboxen ist jedoch nicht immer genau vorhersehbar, da es nicht vollständig spezifiziert ist.Um sicher zu gehen und vorhersehbare Ergebnisse zu erzielen, verwenden Sie immer
.equals()
, um Objekte zu vergleichen, und verlassen Sie sich in diesem Fall nicht auf Autoboxing:quelle