| Autor |
Mensagem |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 28/07/2009 12:19:47
|
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.
|
|
|
 |
|
|
![[Post New]](/templates/default/images/icon_minipost_new.gif) 28/07/2009 12:21:37
|
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.
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 28/07/2009 12:22:36
|
tnaires
GUJ Master
![[Avatar]](/images/avatar/5f6371c9126149517d9ba475def53139.png)
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
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 28/07/2009 12:25:29
|
bKn
Java Ninja
Membro desde: 07/04/2009 15:22:18
Mensagens: 288
Offline
|
Você muda o valor de 2 no cache, é isso?
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 28/07/2009 12:36:25
|
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 |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 28/07/2009 12:40:34
|
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 |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 28/07/2009 12:40:50
|
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ê.
|
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 28/07/2009 12:47:04
|
Mero_Aprendiz
JavaEvangelist
![[Avatar]](/images/avatar/298f587406c914fad5373bb689300433.jpg)
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
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 28/07/2009 12:54:49
|
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.
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 28/07/2009 12:58:25
|
sergiotaborda
GUJ Expert
![[Avatar]](/images/avatar/b4a0e0fbaa9f16d8947c49f4e610b549.png)
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 |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 28/07/2009 12:59:19
|
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.
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 28/07/2009 14:29:33
|
benflodin
JavaGuru
![[Avatar]](/images/avatar/0f6b1f657ac30ab76519ed4c677e9909.jpg)
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 |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 28/07/2009 14:45:18
|
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:
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 28/07/2009 14:53:40
|
benflodin
JavaGuru
![[Avatar]](/images/avatar/0f6b1f657ac30ab76519ed4c677e9909.jpg)
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 |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 28/07/2009 14:57:16
|
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.
|
|
|
 |
|
|