2 + 2 = 5?  XML
Índice dos Fóruns » Java Básico
Autor Mensagem
thingol
Moderador

Membro desde: 29/07/2004 16:10:13
Mensagens: 17543
Offline

Rode o programa abaixo e me expliquem por que é que 2 + 2 = 5.

[WWW]
thingol
Moderador

Membro desde: 29/07/2004 16:10:13
Mensagens: 17543
Offline

Atenção, pessoal mais desesperado: isso não cai na certificação. É só uma curiosidade, e só deve funcionar a partir do Java 5.0.

Mas escrevi isso só para desestimulá-los a tentar usar wrappers como classes mutáveis; isso pode dar confusão, como a que vocês viram acima.
[WWW]
tnaires
GUJ Master
[Avatar]

Membro desde: 22/12/2003 08:05:58
Mensagens: 1678
Localização: Porto Alegre/RS - Natal/RN
Offline

Foi por causa dessa atribuição aqui?

A linha está mudando o valor para 3.

This message was edited 1 time. Last update was at 28/07/2009 12:23:03

bKn
Java Ninja

Membro desde: 07/04/2009 15:22:18
Mensagens: 288
Offline

Você muda o valor de 2 no cache, é isso?
clone_zealot
JavaEvangelist

Membro desde: 21/11/2004 16:40:00
Mensagens: 424
Online

E o fonte compilado está correto... nem podemos culpar o compilador...

This message was edited 2 times. Last update was at 28/07/2009 12:39:15


"Não amo a espada por sua agudez,
não amo a flecha por sua rapidez,
não amo o homem por sua glória,
amo sim, tudo o que eles defendem"
Faramir, Príncipe de Ithilien
andreban
JavaTeenager

Membro desde: 11/07/2006 10:41:57
Mensagens: 188
Localização: Rio de Janeiro
Offline

AahHAahAHa
Mto boa!!



--== http://www.codemansion.com/ ==-- Blog de Desenvolvimento Android e Games

-== http://mobplug.com/ ==-- Simple products, powerful solutions!
SCJA | SJCP | SCJD | SCWCD
thingol
Moderador

Membro desde: 29/07/2004 16:10:13
Mensagens: 17543
Offline

bKn wrote:Você muda o valor de 2 no cache, é isso?


Sim senhor.
Mas o curioso é ver que o resultado é 5 e não 6.
Como vocês viram, só descompilando é que dá para entender por quê.


[WWW]
Mero_Aprendiz
JavaEvangelist
[Avatar]

Membro desde: 25/08/2004 11:32:27
Mensagens: 380
Localização: Goiânia
Offline

thingol wrote:Rode o programa abaixo e me expliquem por que é que 2 + 2 = 5.



Bem, deixa eu ver se entendi:


Já que wrappers são imuatáveis, esse trecho deve criar uma "instância controlada" de Integer com o valor 2 de de referência de controle 2.


Esse trecho altera o valor para 3 da intância controlada de referência 2.


Recupera a instância de referência 2;


Cria uma nova instância de Integer. O valor vem do valor do objeto de referência 2 (com valor 3) mais 2;

Sendo assim:
Valor da referência 2, que é 3, mas 2 = 5.

Estou certo?

[]'s
JL





bKn
Java Ninja

Membro desde: 07/04/2009 15:22:18
Mensagens: 288
Offline

Que massa, 128 pra cima não funciona.. rs

Reflection é traiçoeiro.
sergiotaborda
GUJ Expert
[Avatar]

Membro desde: 22/03/2005 20:57:48
Mensagens: 3433
Offline

thingol wrote:
bKn wrote:Você muda o valor de 2 no cache, é isso?


Sim senhor.
Mas o curioso é ver que o resultado é 5 e não 6.
Como vocês viram, só descompilando é que dá para entender por quê.


Só discordando do "só descompilando".

Operações ariteméticas sempre são feitas com primitivos. Logo, o uso de primitivo em x + 2 é regra. Logo o valor tem que ser trasnformado de integer para int , somado a 2 e voltado a integer. é por isso que nunca se deve usar wrapper em calculos. Auto-(un)boxing não é a pedra filosofal

A outra coisa é saber que os wrapper primitivos fazem cache dos valores mais usado invocados via valueOf(). Ok, isso não é tão regra, mas isso vc descobre pelo primeiro pedaço do codigo.

O ponto é que não ha necessidade de descompilar para saber o resultado.

Criando sua própria API de Validação



Blog do MiddleHeaven
[WWW]
thingol
Moderador

Membro desde: 29/07/2004 16:10:13
Mensagens: 17543
Offline

Mero_Aprendiz wrote:

Bem, deixa eu ver se entendi:


Já que wrappers são imuatáveis, esse trecho deve criar uma "instância controlada" de Integer com o valor 2 de de referência de controle 2.

Wrappers costumam ser imutáveis, a menos que você force a natureza deles e use indevidamente reflection, como fiz acima.



Esse trecho altera o valor para 3 da intância controlada de referência 2.

O trecho acima mexe na instância do Integer que está no cache (não se esqueça - a JVM tem um cache de 256 Integers, que vão de -128 a +127), alterando diretamente o valor do campo "value", que era 2 e passou a ser 3.


Recupera a instância de referência 2;

Na verdade, x = 2 é uma abreviação para x = Integer.valueOf (2), ou seja, ele pega no cache de 256 integers o Integer que seria correspondente ao valor 2. Como fizemos uma agressão ao meio ambiente, aham, como mudamos o valor do campo "value" para 3, então ele pegou um Integer cujo valor agora é 3. Que nojo!


Cria uma nova instância de Integer. O valor vem do valor do objeto de referência 2 (com valor 3) mais 2;

A linha acima é uma abreviação para
x = Integer.valueOf (x.intValue() + 2). Como x.intValue() retorna 3 (devido à agressão ao meio ambiente), então 3 + 2 = 5, e então x recebe um Integer cujo value é 5.

Vejam como a explicação é complicada.

Moral da história: não abusem de reflection para tornar classes imutáveis em "mutáveis" na marra. Você pode acabar tendo problemas difíceis de entender.
[WWW]
benflodin
JavaGuru
[Avatar]

Membro desde: 04/06/2006 13:50:18
Mensagens: 223
Offline

esse cache na verdade é uma especie de mapa que possui um indice com o valor bruto primitivo e valorado a uma referencia wrapper correto?
e é ele que traz a performance para o autoboxing!


think Java
[WWW] [MSN]
thingol
Moderador

Membro desde: 29/07/2004 16:10:13
Mensagens: 17543
Offline

Basta olhar o fonte de java.lang.Integer, que está no arquivo /java/lang/Integer.java dentro de src.zip que está no diretório do JDK.

Lá você pode ver que existe um array estático de Integer, com 256 posições, contendo valores pré-alocados de Integer que vão de -128 a +127.

O método valueOf (que é chamado pelo autoboxing) faz mais ou menos isto aqui:

[WWW]
benflodin
JavaGuru
[Avatar]

Membro desde: 04/06/2006 13:50:18
Mensagens: 223
Offline

é isso mesmo, logo se o objeto( indice n+128 ) sofreu alteração(via reflection) o resultado é o inesperado 2 + 2 = 5

This message was edited 1 time. Last update was at 28/07/2009 14:54:46


think Java
[WWW] [MSN]
jingle
Virtual Machine Man

Membro desde: 04/10/2006 20:40:08
Mensagens: 642
Localização: Canoas/RS
Offline

que divertido isso... da pra se perder legal se usado em uma aplicação.
[Email] [MSN]
 
Índice dos Fóruns » Java Básico
Ir para:   
Powered by JForum 2.1.8 © JForum Team