"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 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
"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 «==»."
int x = 500;
int y = 500;
x == y; //true
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 |
---|---|
|
|
"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 |
---|---|---|
|
|
Le variabili x, y e z contengono riferimenti a diversi oggetti |
|
|
Le variabili x, y e z contengono riferimenti allo stesso oggetto. |
|
|
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:"
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)
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)
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();"
GO TO FULL VERSION