Byte ou int?

6 respostas
hiram

Pessoal,

Um amigo me mandou um código para eu ter pesadelos com Java ehehehe.

Vejam:

public static void main(String args[]) {
    int x = 127;
    int y = 127;
    System.out.println(equal(x,y));
    int w = 128;
    int z = 128;
    System.out.println(equal(w,z));
    Integer a = 3;
    Integer b = 3;
    System.out.println(equal(a,b));
    Integer c = new Integer(1);
    Integer d = new Integer(1);
    System.out.println(equal(c,d));
}

public static boolean(Integer x, Integer y) {
    return (x==y);
}

O retorno esperado pra isso seria, na minha opinião:
true
true
false
false

Entretanto, isso retorna:
true
false
true
false

(1) 127 == 127 (true)
(2) 128 == 128 (false) ???
(3) Integer a e Integer b não fazem referência para o mesmo objeto. a == b (true) ???
(4) Objetos c e d não fazem referência para o mesmo objeto. Portanto: c == d (false)

Alguém pode me dar uma explicação plausível.
Eu utilizei o javap pra disassemblar o código da classe mas ainda assim não encontrei uma explicação interessante.
Tenho lido a JVM specs e quem sabe não encontro algo? :wink:

Valeu!!!

6 Respostas

T
class TesteAutoboxing {
 public static void main(String args[]) {  
     int x = 127;  
     int y = 127;  
     // A linha a seguir equivale a equal(Integer.valueOf(127), Integer.valueOf(127).
     // Na implementação corrente da Sun, Integer.valueOf(127) retorna um objeto Integer
     // presente no cache estático de java.lang.Integer, então equal retorna true.
     System.out.println(equal(x,y)); // true
     int w = 128;  
     int z = 128;  
     // A linha a seguir equivale a equal(Integer.valueOf(128), Integer.valueOf(128).
     // Na implementação corrente da Sun, Integer.valueOf(128) retorna um novo objeto
     // Integer, já que o cache só contém elementos de -128 a +127, então há 2 objetos
     // distintos e equal retorna false.
     System.out.println(equal(w,z));  
     // As linhas a seguir são equivalentes a a = Integer.valueOf(3) e b = Integer.valueOf (3).
     Integer a = 3;  
     Integer b = 3;  
     // Na implementação corrente da Sun, Integer.valueOf(3) retorna um objeto Integer
     // presente no cache estático de java.lang.Integer, então equal retorna true.
     System.out.println(equal(a,b));  
     // Note que a seguir estamos explicitamente criando 2 novos objetos Integer, então equal retorna false.
     Integer c = new Integer(1);  
     Integer d = new Integer(1);  
     System.out.println(equal(c,d));  
 }  

 /** Compara x e y e verifica se são o mesmo objeto, usando == */
 public static boolean equal (Integer x, Integer y) {  
     return (x==y);  
 } 
}
T

Só vou dizer uma coisa: saber que um valor submetido a autoboxing (ou a .valueOf()) pode ser obtido do cache ou não, dependendo se está no intervalo -128 a +127, não é para cair na prova.
E é um detalhe de implementação; tanto é que no próximo update da versão 6, esse intervalo vai poder ser alterado pelo usuário dependendo de um parâmetro da JVM.

nadilsons

A explicação está no método valueOf da Classe Integer

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

thingol:

E é um detalhe de implementação; tanto é que no próximo update da versão 6, esse intervalo vai poder ser alterado pelo usuário dependendo de um parâmetro da JVM.

Olá Thingol,
Onde se pode ter acesso a estas informações?

[]s

hiram

Obrigado Thingol.

A minha pergunta é a mesma. Qual a fonte dessas informações?

T

Quanto à história do Java 6 Update 14,
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6807702 ( http://download.java.net/jdk6/6u14/promoted/b03/changes/JDK6u14.b03.list.html )

Quanto ao cache, isso foi mostrado em vários artigos da época em que o Java 5.0 estava introduzindo essa parte de “autoboxing”. Não sei lhe indicar um artigo desses.

Criado 13 de março de 2009
Ultima resposta 13 de mar. de 2009
Respostas 6
Participantes 3