Autoboxing

Pessoal tem um tópico no livro da Hathy que não entendi, quando li o trecho abaixo tinha certeza que estava errado, mas ao executar exte trecho de código a saida é mesma do livro o que me deixou mais confuso, enfim deixa eu explicar minha duviada quando comparamos i1 com i2 (==) o resultado é que são diferentes, até ai tudo bem pois são objetos diferente s e operador “==” compara referencias, se comparamos com equals() seria iguais pois ai ele compara valores, , porem no trecho B) comparei i2 com i3 com “==” e resultado é que são iguais ao contrario de A, como pode isto?

A)
Integer i1 = 1000;
Integer i2 = 1000;
if(i1 != i2) System.out.println(“different objects”);
if(i1.equals(i2)) System.out.println(“meaningfully equal”);

Produces the output:

different objects
meaningfully equal

B)
Integer i3 = 10;
Integer i4 = 10;
if(i3 == i4) System.out.println(“same object”);
if(i3.equals(i4)) System.out.println(“meaningfully equal”);

This example produces the output:

same object
meaningfully equal

Olá,

A razão para isto é que quando você usa autoboxing, por tras dos panos, utiliza-se o método Integer.valueOf(…) e por exemplo Integer.valueOf(10) sempre retorna o mesmo objeto (a mesma instancia, mesmo) para evitar gastar recursos.

Para mais detalhes, veja esse tópico aqui: http://www.guj.com.br/posts/list/50157.java#263420

[]s,
Sami

As classes Integer e Long, por exemplo, possuem um cache de objetos que estão entre os valores -128 até 127…

Deste modo sempre vamos ter:

Integer i1=127, i2=127;
Integer i3,=128, i4 = 128;
System.out.println(i1 == i2);//true (127 está entre os objetos em cache na JVM)
System.out.println(i3 == i4);//false (128 não entra na brincadeira)

Completando a resposta anterior (que está certa), por esse motivo você NUNCA deve utilizar == para suas comparações de objetos. Vale como regra geral.

Existem raras exceções (i.e. identity collections etc)

Pessoal, Eu entendi a explicação, mas o que não faz sentido para mim é saber que valores pequenos entraram no cache e valores grandes não. Porque teóricamente gastaria mais memória armazenando os valores grandes e menos com os pequenos, então seria mais fácil apontar os valores grandes para a mesma área de memória, não é mesmo?

No caso de int e long, os valores gastos são respectivamente 4 e 8 bytes, não importando se o valor é 0 ou 9223372036854775807. Isso é uma propriedade da representação binária de dados no computador.

Além disso, o cache é bem boboca se você for ver. É só um array de 256 entradas, não é um hashmap como é o cache de strings “internadas” que também existe no Java. Ele é pequeno desse jeito, porque provavelmente devem ter testado um hashmap e esse cache simples e ingênuo, e visto que em algumas aplicações testadas é melhor (mais rápido) ter esse cache bobo que um hashmap.