TL; DR
Java memorizza istanze Integer boxed da -128
a 127
. Poiché stai utilizzando ==
per confrontare i riferimenti agli oggetti invece dei valori , solo gli oggetti memorizzati nella cache corrisponderanno. O lavora con long
valori primitivi unboxed o usa .equals()
per confrontare i tuoi Long
oggetti.
Versione lunga (gioco di parole)
Perché c'è un problema nel confrontare la variabile Long con un valore maggiore di 127? Se il tipo di dati della variabile precedente è primitivo (lungo), il codice funziona per tutti i valori.
Java memorizza nella cache istanze di oggetti Integer compresi tra -128 e 127 . Detto ciò:
- Se si imposta a N variabili lunghe il valore
127
( memorizzato nella cache ), la stessa istanza di oggetto verrà puntata da tutti i riferimenti. (N variabili, 1 istanza)
- Se imposti a N variabili lunghe il valore
128
( non memorizzato nella cache ), avrai un'istanza di oggetto puntata da ogni riferimento. (N variabili, N istanze)
Ecco perché questo:
Long val1 = 127L;
Long val2 = 127L;
System.out.println(val1 == val2);
Long val3 = 128L;
Long val4 = 128L;
System.out.println(val3 == val4);
Emette questo:
vero
falso
Per il valore 127L , poiché entrambi i riferimenti (val1 e val2) puntano alla stessa istanza di oggetto in memoria (memorizzata nella cache), restituisce true
.
D'altra parte, per il valore 128 , poiché non vi è alcuna istanza per esso memorizzato nella cache, ne viene creata una nuova per eventuali nuove assegnazioni per i valori boxed, risultando in due istanze diverse (indicate da val3 e val4) e restituendo false
il confronto tra loro.
Ciò accade solo perché stai confrontando due Long
riferimenti a oggetti , non long
valori primitivi, con l' ==
operatore. Se non fosse per questo meccanismo di cache, questi confronti fallirebbero sempre , quindi il vero problema qui è confrontare i valori boxed con l' ==
operatore.
La modifica di queste variabili in long
tipi primitivi impedirà che ciò accada, ma nel caso in cui sia necessario mantenere il codice utilizzando Long
oggetti, è possibile effettuare questi confronti in sicurezza con i seguenti approcci:
System.out.println(val3.equals(val4)); // true
System.out.println(val3.longValue() == val4.longValue()); // true
System.out.println((long)val3 == (long)val4); // true
(È necessario un corretto controllo dello zero, anche per le fusioni)
IMO , è sempre una buona idea attenersi ai metodi .equals () quando si ha a che fare con i confronti di oggetti.
Link di riferimento:
.longValue()
.