Ist sichergestellt, dass neue Integer (i) == i in Java?
-
26-09-2019 - |
Frage
Betrachten Sie das folgende Snippet:
int i = 99999999;
byte b = 99;
short s = 9999;
Integer ii = Integer.valueOf(9); // should be within cache
System.out.println(new Integer(i) == i); // "true"
System.out.println(new Integer(b) == b); // "true"
System.out.println(new Integer(s) == s); // "true"
System.out.println(new Integer(ii) == ii); // "false"
Es ist offensichtlich, warum die letzte Zeile wird immer druckt "false"
: wir ==
Referenzidentitätsvergleich verwenden, und ein new
Objekt NIE sein ==
zu einem bereits vorhandenen Objekt .
Die Frage ist, über die ersten drei Zeilen: ist diese Vergleiche garantiert auf dem primitiven int
sein, mit der Integer
Auto-unboxed? Gibt es Fälle, in denen die primitiven statt Auto-boxed werden würden, und die Bezugsidentitätsvergleiche durchgeführt werden? (Die alle dann wäre false
!)
Lösung
Ja. JLS §5.6.2 Gibt die Regeln für binäre Zahl Förderung. Im zweiten Teil:
Wenn ein Operator binär gilt numerische Förderung an ein Paar Operanden, von denen jeder muß eine bezeichnen Wert, der in einem numerischen umwandelbar ist Geben Sie die folgenden Regeln gelten, in Um unter Verwendung erweiternde Konvertierung (§5.1.2) zu konvertieren Operanden als erforderlich:
Wenn einer der Operanden ist ein Referenztyp, unboxing Umwandlungs (§5.1.8) durchgeführt wird.
Binary numerische Aktion gilt für mehrere numerischen Operatoren, darunter „die numerische Gleichheit Operatoren == und! =.“
JLS §15.21.1 (Numerical Gleichheitsoperator == und! =) gibt an:
Wenn die Operanden einer Gleichheit Betreiber sind beide numerischen Typ, oder ist von numerischem Typ und den anderen umwandelbar ist (§5.1.8) in numerischen Typ, binäre numerische Förderung ist durchgeführt an den Operanden (§5.6.2).
Im Gegensatz dazu JLS §15.21.3 (! Referenzgleichheitsoperatoren == und =) sieht vor:
Wenn die Operanden einer Gleichheit Bediener sind beide beiden Referenz Typ oder vom Null-Typ, dann wird der Betrieb ist Gegenstand Gleichheit
Dies paßt das gemeinsame Verständnis von Boxen und Unboxing, dass es nur getan, wenn es eine Diskrepanz.
Andere Tipps
Ich werde zunächst erklären, genau dann, wenn ==
ist eine Referenz Gleichheit und genau dann, wenn es ist eine numerische Gleichheit. Die Bedingungen für die Referenz Gleichheit ist einfacher, so dass es zunächst erläutert wird.
JLS 15.21.3 Referenz Gleichheitsoperator ==
und !=
Wenn die Operanden eines Gleichheitsoperator sind beide entweder Referenztyp oder die null Typ, dann ist die Operation Objekt Gleichheit.
Dies erklärt die folgende:
System.out.println(new Integer(0) == new Integer(0)); // "false"
Beide Operanden sind Integer
, die Referenztypen sind, und das ist, warum die ==
reference Gleichheitsvergleich und zwei new
Objekte werden nie ==
zueinander, so dass die, warum er druckt false
.
Für ==
numerische Gleichheit zu sein, mindestens einer der Operanden muss ein numerischer Typ sein ; Dies wird wie folgt angegeben:
JLS 15.21.1 Numerische Gleichheit Operatoren ==
und !=
Wenn die Operanden eines Gleichheitsoperator sind beide von numerischen Typ oder ist numerischer Art und die andere umwandelbar ist , um numerische Typ, binäre numerische Förderung wird auf den Operanden durchgeführt. Wenn die geförderten Typ der Operanden
int
oderlong
ist, wird dann eine ganze Zahl Gleichheitstest durchgeführt wird; wenn der geförderte Typfloat or
double` ist, dann ist ein Floating-Point-Gleichheitstest durchgeführt wird.Beachten Sie, dass binäre Zahlen Förderung führt Wert gesetzt Umwandlung und Unboxing-Konvertierung.
So sollten Sie Folgendes berücksichtigen:
System.out.println(new Integer(0) == 0); // "true"
Diese Drucke true
, denn:
- der rechte Operand ein numerischer
int
Typ - der linke Operand ist umwandelbar ein numerischer Typ, von Unboxing zu
int
- daher
==
ist eine numerische Gleichheit Betrieb
Zusammenfassung
- Wenn beiden Operanden von
==
und!=
sind Referenztypen, es wird immer eine Referenz Gleichheit Betrieb sein- Es spielt keine Rolle, ob die Operanden umwandelbar sind numerische Typen
- Wenn mindestens einer der Operanden ein numerischer Typ ist, wird es immer eine numerische Gleichheit Betrieb sein
- Auto-Unboxing auf einem (höchstens!) Der Operanden wird bei Bedarf durchgeführt werden
Referenzen
- JLS 4.2. Primitive Typen und Werte
- "Die numerische Typen sind die Integral-Typen und die Gleitkommatypen."
- Java Language Guide / Autoboxing
- JLS 5.1.8 Unboxing Conversion
- JLS 15.21.1 Numerische Gleichheit Operatoren
==
und!=
- JLS 15.21.3 Referenz Gleichheitsoperatoren
==
und!=
- JLS 5.6.2 Binary Numeric Promotion