"Poiché gli sviluppatori potevano inventare classi che descrivono i numeri, hanno deciso di essere creativi, come veri sviluppatori".

"In primo luogo, hanno creato una classe Number astratta, da cui derivano Byte, Short, Integer, Long, Float e Double. Dispone di metodi che aiutano a convertire i numeri in altri tipi numerici."

Metodi della classe Number
1
int intValue()
2
long longValue()
3
float floatValue()
4
double doubleValue()
5
byte byteValue()
6
short shortValue()

"Giusto. Dopotutto, non puoi scrivere questo:"

Long x = 100000;
Integer y = (Integer) x;

"Sì, questi tipi non sono primitivi. Ecco perché usiamo i metodi della classe Number:"

Long x = 100000;
Integer y = x.intValue();

"Ma ci sono ancora un paio di cose da considerare. Poiché Integer non è un int, gli oggetti Integer non possono essere confrontati con il classico operatore «==»."

Confronto tra tipi primitivi
int x = 500;
int y = 500;
x == y; //true
Confronto di tipi non primitivi
Integer x = 500;
Integer y = 500;
x == y; //false
x.equals(y); //true

"Esattamente. In qualche modo non ci ho pensato subito."

"Ma c'è di più."

"Mi stai mandando in cortocircuito! Cos'altro c'è?"

"Quando assegniamo un valore int a una variabile Integer, viene chiamato il metodo Integer.valueOf:"

Codice Cosa succede davvero
Integer x = 5;
Integer x = Integer.valueOf(5);

"Sì, l'ho già capito dall'esempio sopra."

"Ma la funzione valueOf non crea sempre un nuovo oggetto Integer."

"Uh, cosa intendi per «non sempre»?"

"Memorizza nella cache i valori da -128 a 127."

Codice Cosa succede davvero Descrizione
Integer x = 300;
Integer y = 300;
Integer z = 300;
Integer x = Integer.valueOf(300);
Integer y = Integer.valueOf(300);
Integer z = Integer.valueOf(300);
Le variabili x, y e z contengono riferimenti a diversi oggetti
Integer x = 100;
Integer y = 100;
Integer z = 100;
Integer x = Integer.valueOf(100);
Integer y = Integer.valueOf(100);
Integer z = Integer.valueOf(100);
Le variabili x, y e z contengono riferimenti allo stesso oggetto.
Integer x = new Integer(10)
Integer y = new Integer(10)
Integer z = 10;
Integer t = 10;
Integer x = new Integer(10)
Integer y = new Integer(10)
Integer z = Integer.valueOf(10);
Integer t = Integer.valueOf(10);
Le variabili z e t contengono riferimenti allo stesso oggetto.

"In altre parole, la situazione è questa:"

1)  Se scriviamo «new Integer()», allora siamo sicuri di ottenere un nuovo oggetto.

2)  Se chiamiamo Integer.valueOf(), esplicitamente o tramite autoboxing, il metodo può restituire un nuovo oggetto o un oggetto memorizzato nella cache se l'argomento numero è compreso nell'intervallo da -128 a 127.

"Cosa c'è di così terribile nel metodo che restituisce un oggetto dalla cache?"

"Non importa. Devi solo sapere che a volte, quando non te lo aspetti, gli oggetti potrebbero essere uguali. Tutto con l'uguaglianza è complicato. Se confrontiamo un primitivo con un non primitivo, allora vengono confrontati come primitivi:"

Problema di confronto
int x = 300;
Integer y = 300;
Integer z = 300;

x == y; //true (comparison based on primitive value)
x == z; //true (comparison based on primitive value)
y == z; //false (comparison based on references)
Un esempio ancora più interessante. La cache entra nell'immagine qui
int x = 100;
Integer y = 100;
Integer z = 100;

x == y; //true (comparison based on primitive value)
x == z; //true (comparison based on primitive value)
y == z; //true (comparison based on references; they point to the same object)
Ma la cache non è coinvolta qui
int x = 100;
Integer y = new Integer(100);
Integer z = 100;

x == y; //true (comparison based on primitive value)
x == z; //true (comparison based on primitive value)
y == z; //false (comparison based on references; they point to different objects)

"Fantastico... E come memorizzerò tutto questo?"

"Non hai bisogno di memorizzarlo. Devi solo capire come è organizzato tutto questo e cosa succede realmente quando entrano in gioco un primitivo e la sua controparte non primitiva."

"Ti consiglio anche di guardare i metodi della classe Integer. Ha alcuni metodi buoni e utili. Ne hai persino usato uno abbastanza spesso."

"Sì, mi ricordo. Integer.parseInt();"