Primitivi inscatolati ed equivalenza

Così mi è stata fatta questa domanda oggi.

Integer a = 3; Integer b = 2; Integer c = 5; Integer d = a + b; System.out.println(c == d); 

Cosa stamperà questo programma? Ritorna vero. Ho risposto che verrà sempre stampato falso a causa di come ho capito la boxe automatica (e auto-dis). Ho avuto l’impressione che l’assegnazione di Integer a = 3 crei un nuovo Intero (3) in modo che un == valuti il ​​riferimento piuttosto che il valore primitivo.

Qualcuno può spiegarlo?

I valori in box compresi tra -128 e 127 vengono memorizzati nella cache. La boxe utilizza il metodo Integer.valueOf , che utilizza la cache. I valori al di fuori dell’intervallo non vengono memorizzati nella cache e vengono sempre creati come una nuova istanza. Poiché i tuoi valori rientrano nell’intervallo memorizzato nella cache, i valori sono uguali usando l’operatore ==.

Citazione dalle specifiche del linguaggio Java:

Se il valore p in box è true, false, un byte, un char nell’intervallo da \ u0000 a \ u007f o un numero int o short compreso tra -128 e 127, allora r1 e r2 saranno i risultati di due conversioni di boxing di p. È sempre il caso che r1 == r2.

http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.7

Questo è ciò che sta realmente accadendo:

 Integer c = Integer.valueOf(5); Integer d = Integer.valueOf(a.intValue() + b.intValue()); 

Java mantiene una cache di oggetti Integer tra -128 e 127. Confrontati con quanto segue:

 Integer a = 300; Integer b = 200; Integer c = 500; Integer d = a + b; System.out.println(c == d); 

Quale dovrebbe stampare false .

È perché alcuni degli interi (auto-inscatolati) vengono memorizzati nella cache, quindi in realtà stai confrontando lo stesso riferimento: questo post contiene esempi più dettagliati e una spiegazione.

Il caching avviene anche al di fuori del selfboxing, considera questo:

 Integer a = 1; Integer b = new Integer(1); Integer c = Integer.valueOf(1); System.out.println(a == b); System.out.println(b == c); System.out.println(c == a); 

questo stamperà:

 false false true 

Quindi immagino che generalmente vuoi stare lontano da ‘==’ quando confronti Oggetti