Tipos primitivos x Classes

Pessoal, estava estudando orientação a objetos e, pela minha lógica, quando fazemos: Integer x = new Integer(100);, x guardaria o valor da referência na memoria de um objeto da classe Integer, Certo? Logo se tivermos o código abaixo:

Integer x = new Integer(100);
Integer y = new Integer(100);
if(x == y)
System.out.println(“Sao Iguais”);

O programa não mostra o “Sao Iguais” pois apontam para objetos diferentes (precisariamos comparar x.equals(y)) . Porém se tivermos o código abaixo:
Integer x = new Integer(100);
int y = 100;
if(x == y)
System.out.println(“Sao Iguais”);

O programa passa no if e exibe o “Sao Iguais” como pode acontecer isso??

Boa madrugada Colegas !

Ops… falei besteira.
Mas aqui

if (x == y)

funcionou…

[]s

Mas funcionou nesse caso:

Integer x = new Integer(100);
Integer y = new Integer(100);
if(x == y)
System.out.println(“Sao Iguais”);

Quero dizer, o seu programa exibe a mensagem “Sao Iguais”???

Valeu.

Boa madrugada Colegas !

Não… nesse caso você tem que usar o equals mesmo…

[]s

O java tem um cache interno, que vai de -128 até 128 (1 byte). Assim, tipos criados com autoboxing (ou seja, automaticamente convertidos de int para Integer), tentam sempre que possível utilizar esse cache.

Ou seja, quando você faz:

Integer x = 100; //Cria um novo objeto e adiciona ao cache
Integer y = 100; //Reusa o objeto do cache
Integer z = 100; //Reusa o objeto do cache

O java vai até uma tabelinha, que contém vários Integer já criados (de -128 até 128 ), acha lá o objeto que corresponde ao 100, e usa esse objeto nos três casos. Se o 100 ainda não foi usado, um novo objeto será criado e adicionado a essa tabela, para então ser reusado em novas conversões. Como no fundo as três referências contém efetivamente o mesmo objeto, comparações com == irão funcionar. Isso é vantajoso pois o equals funciona mais rápido em objetos idênticos. Já que uma implementação típica começará testando pela identidade:

public void equals(Object other) { if (other == this) return true; if (other.getClass() != Integer.class) return false; return value == ((Integer)other).value; }

Você pode pedir explicitamente para não usar o cache através do comando new. Se fizer:

Integer x = new Integer(100); //Cria um novo objeto e o adiciona ao cache
Integer y = new Integer(100); //Ignora o cache e cria um novo objeto
Integer z = new Integer(100); //Ignora o cache e cria um novo objeto

Terá objetos diferentes.

Via de regra, a comparação com == em objetos diz se eles são o mesmo objeto, isto é, se ocupam a mesma posição de memória. Ele não testa igualdade, mas sim, identidade.

Com objetos a única coisa que testa igualdade é o método equals. A definição de igualdade entre dois objetos é relativa. No caso do Integer é clara, dois objetos desse tipo são iguais sempre que seu valor inteiro interno for igual.

Outra forma de usar o cache, é criando inteiros através do método valueOf, ao invés do new:

Integer x = Integer.valueOf(100); //Usa do cache, se tiver lá.

Esse cache existe para todos os objetos que representam inteiros: Byte, Short Integer e Long.

autoboxing…

como tem um primitivo na comparação, o == funciona como em tipos primitivos…

Nesse caso, é auto-unboxing.

Realmente, comparar Integer com int, o Integer será convertido para int antes da comparação.

Assim:

int x = 100; Integer y = new Integer(100); if (x == y)

Equivale à:

int x = 100; Integer y = new Integer(100); if (x == y.intValue())

Com direito inclusive a NullPointerException, caso a variável y seja nula.

Bom dia Colegas !

ViniGodoy:

Show de bola sua explicação !
Mas se puder exclarecer mais uma dúvida, eu ficaria muito grato !

No caso de:


Integer x = 100;
Integer y = 100;

if (x == y)
...
...

A comparação que é feita é se trata-se do mesmo objeto ou se os valores são iguais ?
O rissato disse alguma coisa sobre autoboxing…

[]s

Por que se trata do mesmo objeto. Quando ambos são objetos, não existe o unboxing.

Só existe se um deles for objeto e o outro um tipo primitivo.

Ok, muito obrigado, vocês realmente tiraram minha dúvida.

Boa tarde, tenho outra dúvida, não consegui entender o que o operador ^ faz exatamente no código abaixo, quero dizer, porque é que o resultado de b é 5?

public class Programa {
public static void main (String []args){

	byte b = 10; // 00001010 binary
	byte c = 15; // 00001111 binary
	b = (byte) (b^c);
	System.out.println("Conteudo de b: " + b);
}

}

Você só vai entender se olhar para os bits, não para o valor decimal.
Esse operador é o de ou exclusivo, ou XOR.

O que ele faz é o seguinte. Todo lugar que os bits em A e B foram idênticos, ele retorna 0. Caso contrário, ele retorna 1.
assim:
00001010 ^
00001111

00000101 (5 decimal).

Note que essa é uma operação reversível.
00000101 ^
00001111

00001010

00000101 ^
00001010

00001111

Não é a toa que isso é usado em criptografia. Escolha um número qualquer, aplique o XOR dele em todos os bytes de um arquivo e você terá um arquivo com uma criptografia simétrica simples. Para retornar ao arquivo original, basta reaplicar o XOR com o mesmo número em todos os bytes novamente. Esse número, que só você saberá qual foi, é a chave do seu algoritmo.

Para ver a lista completa dos operadores, veja:
http://java.sun.com/docs/books/tutorial/java/nutsandbolts/opsummary.html

Rasa, só um pedido, pode ler esse post aqui?
http://www.guj.com.br/posts/list/50115.java

Ele vai te ensinar a como formatar códigos corretamente aqui no fórum, usando a tag code. Ajuda muito para a gente ter o código todo colorido. Ele também ensina alguns outros recursos do fórum. :wink:

Muito obrigado, estava mesmo tentando colocar o meu código deste jeito, pode deixar que usarei esses recursos, quanto ao operador de XOR endendi como funciona, Valeu pela explicação.

Opa pessoal, alguém saberia me dizer para que serve o operador >> do java?

Grato?

Ele afasta os bits n casas para direita.

00101100 >> 1

00010110