Comparando tipos Wrapers

13 respostas
derheimen

Estou com dúvidas em relação a classes Wrapers.
Por que o método equals() em alguns casos retornam “true” e em outros “false”.

Exemplo:

public class Boxing4 { public static void main(String[] args) { Integer i = 10; Integer j = 10; System.out.println((i == j) +" / "+ (i.equals(j))); } }
Resultado: true / true

Neste outro exemplo:

public class Boxing4 { public static void main(String[] args) { Integer z = 200; Integer x = 200; System.out.println((z == x) +" / "+ (z.equals(x))); } }
Resultado: false / true

Esta dúvidas foram tiradas das questões 4 e 5 do mock abaixo.
http://www.javabeat.net/javabeat/scjp5/mocks/BoxingConversion-10questions.php

Não entendi muito bem a explicação das respostas.
Aguém poderia dar um help???

13 Respostas

ziegfried

Suponho q seja pq Integer não possui o tal pool interno q as Strings possuem. Quando o operador == é usado com objetos, ele verifica se os mesmos estão no mesmo local da memória. Já o método equals() verifica o conteúdo dos objetos. Nesta segunda saída, provavelmente os dois objetos não estavam no mesmo local de memória. Se fosse com Strings, daria true pois a JVM mantém o pool interno de Strings para economizar memória, fazendo com que atribuições a uma mesma String setada anteriormente sejam guardadas no mesmo local.

Espero ter esclarecido! Boa sorte!

gbmesso

Pra mim ainda não está muiiiito claro também mas vou estudar e ler
Porém veja aqui algo que possa ajudar: http://www.guj.com.br/posts/list/48112.java

Detalhe, sempre que eu compilo e executo a saída é FALSE e TRUE.

Alguém pode nos ajudar nessa ?

Guilherme_Moreira

Posso estar falando besteira, mas quando você cria Integer assim:

Integer = 20;

e o número estiver entre -128 à 127, ele vai usar um pool de inteiros, por isso o endereço é o mesmo.

repetindo isso é uma suposição, eu acho que eu já vi isso em algum lugar

rodrigo_gomes

Olá, o operador “==” sempre vai funcionar para os seguintes wrappers:

  • Boolean
  • Byte
  • Shot e Integer (de -128 a 127)
  • Character (de \u0000 até \u007f)

Como no primeiro exemplo o valor dos Integers eram 10, então ok está dentro da faixa
-128 a 127.
O que não ocorre no caso seguinte

[]´s

derheimen

hum… entendi agora.
valeu a todos pela ajuda.

Sami_Koivu

rodrigo_gomes:
Olá, o operador "==" sempre vai funcionar para os seguintes wrappers:

  • Boolean
  • Byte
  • Shot e Integer (de -128 a 127)
  • Character (de \u0000 até \u007f)

Só acrescentando que isso não vale se os wrappers são criados explicitamente com a palavra-chave new.

Quando se usa o autoboxing, por trás dos panos é utilizado o método valueOf(…).

Segue o código do método Integer.valueOf(int):

public static Integer valueOf(int i) {
        final int offset = 128;
        if (i &gt= -128 && i &lt= 127) { // must cache 
            return IntegerCache.cache[i + offset];
        }
        return new Integer(i);
    }

Então quando o valor está entre -128 e 127 o código retorna um Integer de um array, "reutilizando" um objeto criado anteriormente, senão ele cria um objeto novo.

Vale talvez notar que os wrappers são imutáveis, pois daria problemas se não fossem. Imaginem um trecho de código pegando um objeto Integer de valor 3 dessa cache e mudando o valor para 7. Daí outro trecho de código tentaria pegar o 3 da cache, mas acabaria recebendo esse 7. O compartilhamento desses objetos (tanto como o das Strings) funciona graças a serem imutáveis.

[]s,
Sami

gbmesso

Sami Koivu:
rodrigo_gomes:
Olá, o operador "==" sempre vai funcionar para os seguintes wrappers:

  • Boolean
  • Byte
  • Shot e Integer (de -128 a 127)
  • Character (de \u0000 até \u007f)

Só acrescentando que isso não vale se os wrappers são criados explicitamente com a palavra-chave new.

Quando se usa o autoboxing, por trás dos panos é utilizado o método valueOf(…).

Segue o código do método Integer.valueOf(int):

public static Integer valueOf(int i) {
        final int offset = 128;
        if (i &gt= -128 && i &lt= 127) { // must cache 
            return IntegerCache.cache[i + offset];
        }
        return new Integer(i);
    }

Então quando o valor está entre -128 e 127 o código retorna um Integer de um array, "reutilizando" um objeto criado anteriormente, senão ele cria um objeto novo.

Vale talvez notar que os wrappers são imutáveis, pois daria problemas se não fossem. Imaginem um trecho de código pegando um objeto Integer de valor 3 dessa cache e mudando o valor para 7. Daí outro trecho de código tentaria pegar o 3 da cache, mas acabaria recebendo esse 7. O compartilhamento desses objetos (tanto como o das Strings) funciona graças a serem imutáveis.

[]s,
Sami

Rodrigo e Sami, parabéns pela explicação !!!

Acho que nem em livro teríamos uma explicação tão interessante.

Acho que é uma boa idéia começar a utilizar + wrappers em nossas classes pois esse lance de cache é bem legal.
Não vi nada igual em outra linguagem (q eu conheço)

Abs

derheimen

Faltou esclarecer outros detalhes em relação a essas classes Wraper.

Integer i = new Integer(10);
Integer j = new Integer(10);
System.out.println((i == j) +" / "+ (i.equals(j)));

Saida : false / true

Quando se compara esses tipos wrapers e estes forem inicializados usando a a palavra chave “new”, o == compara as referências, como neste caso são dois objetos distintos o resultado será falso.

Já o equals compara dois objetos diferentes para saber se seus conteúdos são iguais.

rodrigo_gomes

Heider Matos:
Faltou esclarecer outros detalhes em relação a essas classes Wraper.

Quando se compara esses tipos wrapers e estes forem inicializados usando a a palavra chave “new”, o == compara as referências, como neste caso são dois objetos distintos o resultado será falso.

O Sami já tinha explicado.

Sami Koivu:
Só acrescentando que isso não vale se os wrappers são criados explicitamente com a palavra-chave new.

Quando se usa o autoboxing, por trás dos panos é utilizado o método valueOf(…).
.

[]´s

derheimen

Estava eu fazendo uns pequenos testes e me deparei com outra dúvida.

Resultado :truetrue

Por que “x” no 1º print é maior que “y” e retorna true???
Já no 2º print “x” é menor que “y” e também retorna true ???

Não entendi estes resultados, os valores deles são iguais!!!
Oque ocorre em tempo de execução ???
Boxing, etc e tal… rsrsrsrsrs
Me ajudem ai…

Sami_Koivu

Olá,

= na verdade significa maior ou igual e <= significa menor ou igual. Utilize < e > para o efeito que você quis. Nesse caso não é questão de boxing :slight_smile:

[]s,
Sami

derheimen

Cara, pior que vc ta certo…
Como sou um tonto, nem prestei atenção nesse detalhe.

Estou estudando todos os dias, o dia todo, acho que chega alguns momentos que estou muito cansado, que não consigo pensar mais direito e acaba ocorrendo esses tipos de coisas.:lol: :lol: :lol: :lol:

Fiquei até com vergonha agora. Foi mal ai… Fuiiiiiiiiii.

Sami_Koivu

Não tem porquê. Acontece (com todo mundo - ou pelo menos comigo também). Faz parte. Normal :slight_smile:

[]s,
Sami

Criado 16 de janeiro de 2007
Ultima resposta 17 de jan. de 2007
Respostas 13
Participantes 6