TL; DR
Java memorizza istanze Integer boxed da -128a 127. Poiché stai utilizzando ==per confrontare i riferimenti agli oggetti invece dei valori , solo gli oggetti memorizzati nella cache corrisponderanno. O lavora con longvalori primitivi unboxed o usa .equals()per confrontare i tuoi Longoggetti.
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 falseil confronto tra loro.
Ciò accade solo perché stai confrontando due Long riferimenti a oggetti , non longvalori 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 longtipi primitivi impedirà che ciò accada, ma nel caso in cui sia necessario mantenere il codice utilizzando Longoggetti, è 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().