Pergunta

Considere este código:

class test {
   public static void main(String[] args) {
      test inst_test = new test();
      int i1 = 2000;
      int i2 = 2000;
      int i3 = 2;
      int i4 = 2;
      Integer Ithree = new Integer(2); // 1
      Integer Ifour = new Integer(2); // 2
      System.out.println( Ithree == Ifour );
      inst_test.method( i3 , i4 );
      inst_test.method( i1 , i2 );
   }
   public void method( Integer i , Integer eye ) {
      System.out.println(i == eye );
   }
}

Imprime:

false
true
false

Eu entendo o primeiro false, o operador == verifica apenas se duas referências estão trabalhando no mesmo objeto, que neste caso não são.

A seguir true e false Faça -me coçar a cabeça. Por que Java consideraria i3 e i4 igual, mas i1 e i2 diferente? Ambos foram embrulhados para inteiro, não deveriam Ambas avaliar como falso? Existe uma razão prática para essa inconsistência?

Foi útil?

Solução

Autoboxing de primitivas em objetos (conforme usado em suas chamadas para method usa um cache de pequenos valores. De Especificação de idiomas Java Seção 5.1.7:

Se o valor p sendo em caixa for verdadeiro, falso, um byte, um char no intervalo u0000 a u007f ou um número int ou curto entre -128 e 127, depois que R1 e R2 sejam os resultados de quaisquer duas conversões de boxe de p. É sempre o caso que R1 == R2.

A discussão parte das especificações imediatamente seguintes que é interessante também. Notavelmente uma JVM pode armazenar em cache mais valores se quiser - você não pode ter certeza dos resultados de fazer:

Integer i1 = 129;
Integer i2 = 129;
boolean b = (i1 == i2);

Outras dicas

Ao auto -boxing, os números inteiros entre -128 e 127 são armazenados em cache e o mesmo objeto de wrapper é retornado. O mesmo com valores booleanos e valores de char entre u0000 e u007f

É isso que você ganha a maior parte do tempo, no entanto, depende da implementação da JVM.

Isso ocorre porque o boxe faz com que os números inteiros abaixo de um determinado valor (128, eu acho) se referem a algum objeto pré -construído e valores mais altos para novos objetos.

Usos autoboxing Integer.valueof (i), não novo inteiro (i), para construir um objeto de classe inteira.

Como os outros disseram, o ValueOf () usa um cache, principalmente para eficiência espacial.

Não use == nos tipos de referência, quase sempre é um erro.

A classe inteira contém um cache de algumas instâncias usadas com frequência. O intervalo de valores geralmente varia de JVM para JVM (às vezes também é configurável), mas em geral o código relevante é algo como:

public static Integer valueOf(int i) {
    if(i >= -128 && i <= IntegerCache.high)
        return IntegerCache.cache[i + 128];
    else
        return new Integer(i);
}

(Código do Sun JDK 1.6)

Isso é como o intervalo de string, pois economiza memória e permite a igualdade de teste usando uma referência (por exemplo == no lugar de é igual a)

Eu acho que o embrulho tenta minimizar o número de objetos inteiros e cria apenas um objeto que representa 2 também salvar memória.

Lembre -se de nunca usar == em objetos que você nunca sabe o que acontece.

A autoboxing usa algum mecanismo de armazenamento em cache. Normalmente você nunca deve confiar em ==, sempre use equals para verificar a igualdade.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top