È garantito che new Integer(i) == i in Java?
-
26-09-2019 - |
Domanda
Si consideri il seguente frammento:
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"
E ' ovvio perché l'ultima riga SEMPRE stampe "false"
:stiamo usando ==
di riferimento di identità confronto, e una new
oggetto MAI essere ==
per un oggetto già esistente.
La domanda è sulle prime 3 righe:sono quelli confronti garantito per essere sul primitivo int
, con il Integer
auto-unboxed?Ci sono casi in cui la primitiva sarebbe auto-boxed, invece, di riferimento e di identità vengono eseguiti i confronti?(che sarebbe poi essere false
!)
Soluzione
Sì. JLS §5.6.2 specifica il norme per la promozione numerico binario. In parte:
Quando un operatore applica binario promozione numerico ad una coppia di operandi, ciascuno dei quali deve denotare valore che è convertibile in un numerico tipo, si applicano le seguenti regole, in ordine, conversione utilizzando ampliamento (§5.1.2) per convertire operandi necessaria:
Se uno degli operandi è di un tipo di riferimento, conversione unboxing (§5.1.8) viene eseguita.
promozione numerico binario vale per diversi operatori numerici, tra cui "The operatori di uguaglianza numerica == e! =".
JLS §15.21.1 (Numerical uguaglianza Gli operatori == e! =) specifica:
Se gli operandi di parità operatore sono entrambi di tipo numerico, o uno è di tipo numerico e l'altra è convertibile (§5.1.8) a numerico tipo, promozione numerico binario è eseguita sui operandi (§5.6.2).
Al contrario, JLS §15.21.3 (! Riferimento uguaglianza Gli operatori == e =) prevede:
Se gli operandi di parità operatore sono entrambi sia riferimento digitare o il tipo nullo, allora il operazione è uguaglianza oggetto
questo si inserisce l'intesa comune di boxe e unboxing, il gioco è fatto solo fatto quando c'è una mancata corrispondenza.
Altri suggerimenti
In primo luogo, vorrei spiegare proprio quando ==
è un riferimento di uguaglianza e di proprio quando è un valore numerico per l'uguaglianza.Le condizioni di riferimento per l'uguaglianza è più semplice, così sarà spiegato prima.
JLS 15.21.3 di Riferimento per gli Operatori di Uguaglianza ==
e !=
Se gli operandi di un operatore di uguaglianza sono sia di tipo di riferimento o il null tipo, allora l'operazione è oggetto di uguaglianza.
Questo spiega il seguente:
System.out.println(new Integer(0) == new Integer(0)); // "false"
Entrambi gli operandi sono Integer
, quali sono i tipi di riferimento, e per questo motivo il ==
è di riferimento per il confronto di uguaglianza, e due new
gli oggetti non saranno mai ==
a vicenda, in modo che il motivo per cui le stampe false
.
Per ==
per essere la parità numerica, almeno uno degli operandi deve essere di tipo numerico;questo è specificato come segue:
JLS 15.21.1 Numerico Operatori di Uguaglianza ==
e !=
Se gli operandi di un operatore di uguaglianza sono entrambi di tipo numerico, o uno è di tipo numerico e l'altro è convertibile di tipo numerico, numerico binario promozione è effettuata sulla operandi.Se l'promosso tipo degli operandi è
int
olong
, poi un intero test di uguaglianza viene eseguita;se il tipo è promossofloat or
doppia", quindi un punto mobile di uguaglianza test viene eseguito.Nota che numerici binari promozione svolge valore di set di conversione e unboxing di conversione.
Quindi, considerare quanto segue:
System.out.println(new Integer(0) == 0); // "true"
Questa stampa true
, perché:
- l'operando di destra è numerico
int
tipo - l'operando di sinistra è convertibile un tipo numerico, con l'unboxing di
int
- quindi
==
è un valore numerico per l'uguaglianza di funzionamento
Riepilogo
- Se entrambi gli operandi di
==
e!=
sono i tipi di riferimento, sarà sempre un riferimento uguaglianza operazione- Non importa se gli operandi sono convertibili per i tipi numerici
- Se almeno uno degli operandi è un tipo numerico, sarà sempre un valore numerico per l'uguaglianza di funzionamento
- Auto-unboxing su uno (al massimo!) degli operandi sarà eseguita, se necessario,
Riferimenti
- JLS 4.2.Tipi primitivi e di Valori
- "Il tipi numerici sono i tipi integrali e i tipi a virgola mobile."
- Linguaggio Java-Guida/Autoboxing
- JLS 5.1.8 Unboxing di Conversione
- JLS 15.21.1 Numerico Operatori di Uguaglianza
==
e!=
- JLS 15.21.3 di Riferimento per gli Operatori di Uguaglianza
==
e!=
- JLS 5.6.2 Numerici Binari Promozione