Boxing, == e equals() --- ampliação e boxing

6 respostas
D

olá a todos

tenho duas duvidas a respeito da certificação scjp6. As duas são com respeito ao livro KS&BB.

duvida 1
boxing, == e equals()

no livro diz que

Integer i1 = 10;
Intege i2 = 10;

se(i1 != i2)   
      System....("objetos diferentes");      //são mesmo objetos diferentes

se(i1.equals(i2))    
      System......("relativamente iguais");     //são iguais porque seus valores são iguais

se(i1 == i2)
      System......("objetos iguais");          //são iguais pois são instancias de Integer

Até entendi o código acima, mas na minha máquina não funcionou como esperado. O primeiro if tem resultado false, então não imprime “objetos diferentes” como mostra no livro.

Entendi na explicação do livro(inglês e port) que tanto o teste != quanto == deveriam ser true nas comparações de duas instancias Integer com valores iguais.

Estou correto ou entendi mal? Ou o livro explica mal?

Dúvida 2

O livro diz que não é possivel ampliar um tipo wrapper. Corretissimo. Um Integer não pode se transformar num Long.

O livro diz que não é possível ampliar e depois fazer boxing.

O que seria a ampliação do código abaixo? Ampliar o byte? Ampliar no que? Ampliar o byte primitivo para um long primitivo para depois fazer do long um Long e passar para o método não pode?

class WidenAndBox {
  static void go(Long x) { System.out.println("Long"); }
  public static void main(String [] args) {
    byte b = 5;
    go(b);           // must widen then box - illegal
  }
}

6 Respostas

pmlm

Para aumentar as tuas dúvidas… :slight_smile:

Experimenta este código

Integer i1 = 127;
Integer i2 = 127;
Integer i3 = 128;
Integer i4 = 128;
        
System.out.println(i1 == i2);
System.out.println(i3 == i4);

Qual é que achas que vai ser o resultado?

gomesrod

dio.msg:

Integer i1 = 10;
Intege i2 = 10;

se(i1 != i2)   
      System....("objetos diferentes");      //são mesmo objetos diferentes

se(i1.equals(i2))    
      System......("relativamente iguais");     //são iguais porque seus valores são iguais

se(i1 == i2)
      System......("objetos iguais");          //são iguais pois são instancias de Integer

(…) O primeiro if tem resultado false, então não imprime “objetos diferentes” como mostra no livro.


Está certo, ele tem que imprimir a segunda e a terceira mensagens. O porque disso é uma longa história… Faça o teste que o colega colocou aí em cima e reflita sobre os resultados…
Aí você volta aqui para falar sobre suas conclusões.

Isso jamais vai acontecer em nenhuma situação! Tanto com números quanto com qualquer coisa em Java, retornar true tanto para == como para != não é possível.
O que acontece é que em determinadas situações vai ser true e em outras vai ser false (tem a ver com o problema anterior…)

Exatamente o que você disse: não pode Ampliar o byte primitivo para um long primitivo para depois fazer do long um Long e passar para o método.
Mas você pode fazer de maneira explícita se quiser, assim:

byte b = 5;
long l = b;      // Fez  a ampliação - ok.
go(l);           // Fez o boxing de long para Long - ok
D

o valor limite do wrapper determina o resultado do teste ser true ou false.
<=127 = true

=128 = false

para wrappers Integer

e …

todos os wrapper funcionam assim? Qual o limite de cada um deles?

Fiz o teste mudando Integer i1 e i2 para Double i1 e i2 e o resultado foi falso na igualdade. Acho que deveria ser true no valor 127.1

muito estranho!!!

pmlm

Os valores mais pequenos são cached, daí ele ao comparar i1 e i2 vai comparar os valores primitivos cached 127 com 127 e dá true. Ao comparar i3 e i4, os valores já não estão cached e está a comparar os objectos que são diferentes e dá false.

Se voltares ao teu exemplo e, em vez de 10 usares, por exemplo, 1000 vais ver que os resultados são diferentes.

Atenção que este valor 127 é o valor utilizado pela implementação da Sun, não quer dizer que outras não usem outro valor, pelo que não se deve confiar nestes valores no desenvolvimento de código.

Podes ler mais sobre Autoboxing em http://www.java-tips.org/java-se-tips/java.lang/introduction-to-autoboxing-4.html

D

Encontrei o post abaixo que responde um pouco das minhas dúvidas. Vou olhar o sugerido pelo pmlm tambem e se tiver duvida ainda pergunto de novo.

http://www.guj.com.br/posts/list/134521.java#723845

D

olá novamente

fiz o seguinte teste e descobri o pulo do gato

equals compara o valor dentro do wrapper
== compara se as variáveis referenciam um mesmo endereço no intervalo fechado [-128, 127]. Se for o mesmo valor do intervalo, true, se forem valores diferentes ou se os valores ultrapassarem o 127, false.

Na forma simples de criação do wrapper, respeitando o intervalo, == é true para valores iguais e false para valores diferentes. Se usarmos a forma de criação “new Wrapper(x)” mesmo que os valores sejam iguais, == será sempres false, ao passo que equals() será true se os valores forem iguais e false se os valores forem diferentes.

Me corrijam se estou enganado

public class IntegerTest{
	public static void main(String[] args){
	 Integer i1 = 127;  
	 Integer i2 = 127;  
	 Integer i3 = 128;  
	 Integer i4 = 128;  
	      	     
	 System.out.println(i1 == i2);  
	 System.out.println(i3 == i4);	

	Integer i5 = new Integer(127);
	Integer i6 = new Integer(127);
	System.out.println(i5 == i6);
	System.out.println(i5.equals(i6));

	Integer i7 = new Integer(128);
	Integer i8 = new Integer(128);
	System.out.println(i7 == i8);
	System.out.println(i7.equals(i8));

	}
}

resultado

true
false
false
true
false
true
Criado 21 de dezembro de 2009
Ultima resposta 21 de dez. de 2009
Respostas 6
Participantes 3