"Como os desenvolvedores podem criar classes que descrevam números, eles decidiram ser criativos, como desenvolvedores reais."
"Primeiro, eles criaram uma classe abstrata Number, da qual Byte, Short, Integer, Long, Float e Double são derivados. Ela possui métodos que ajudam a converter números em outros tipos numéricos."
Métodos da classe Number | |
---|---|
1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
"Certo. Afinal, você não pode escrever isso:"
Long x = 100000;
Integer y = (Integer) x;
"Sim, esses tipos não são primitivos. É por isso que usamos os métodos da classe Number:"
Long x = 100000;
Integer y = x.intValue();
"Mas ainda há algumas coisas a considerar. Como Integer não é um int, os objetos Integer não podem ser comparados com o clássico operador «==»."
int x = 500;
int y = 500;
x == y; //true
Integer x = 500;
Integer y = 500;
x == y; //false
x.equals(y); //true
"Exatamente. De alguma forma eu não pensei nisso imediatamente."
"Mas há mais."
"Você está causando um curto-circuito em meus circuitos! O que mais há?"
"Quando atribuímos um valor int a uma variável Integer, o método Integer.valueOf é chamado:"
Código | O que realmente acontece |
---|---|
|
|
"Sim, eu já entendi isso do exemplo acima."
"Mas a função valueOf nem sempre cria um novo objeto Integer."
"Uh, o que você quer dizer com 'nem sempre'?"
"Ele armazena em cache valores de -128 a 127."
Código | O que realmente acontece | Descrição |
---|---|---|
|
|
As variáveis x, y e z contêm referências a diferentes objetos |
|
|
As variáveis x, y e z contêm referências ao mesmo objeto. |
|
|
As variáveis z e t contêm referências ao mesmo objeto. |
"Em outras palavras, a situação é esta:"
1) Se escrevermos «new Integer()», temos a garantia de obter um novo objeto.
2) Se chamarmos Integer.valueOf(), explicitamente ou através de autoboxing, então o método pode retornar um novo objeto ou um objeto em cache se o argumento de número estiver no intervalo de -128 a 127.
"O que há de tão terrível no método que retorna um objeto do cache?"
"Não importa. Você só precisa saber que às vezes, quando você não está esperando, os objetos podem ser iguais. Tudo com igualdade é complicado. Se compararmos um primitivo com um não primitivo, então eles são comparados como primitivos:"
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)
"Ótimo... E como vou memorizar tudo isso?"
"Você não precisa memorizar isso. Você só precisa entender como tudo isso é organizado e o que realmente acontece quando um primitivo e sua contraparte não primitiva entram em jogo."
"Eu também recomendo que você dê uma olhada nos métodos da classe Integer. Ela tem alguns métodos bons e úteis. Você até já usou um deles com frequência."
"Sim, eu me lembro. Integer.parseInt();"
GO TO FULL VERSION