ti-enxame.com

Por que o operador equal funciona para o valor Integer até 128 number?

Por que Integer "=" operator não funciona para 128 e depois de valores inteiros? Alguém pode explicar essa situação?

Este é o meu ambiente Java: versão Java "1.6.0_37"

Java (TM) SE Runtime Environment (build 1.6.0_37-b06)

Java HotSpot (TM) Servidor de 64 bits VM (compilação 20.12-b01, modo misto)

Código de amostra:

    Integer a;
    Integer b;
    a = 129;
    b = 129;

    for (int i = 0; i < 200; i++) {
        a = i;
        b = i;

        if (a != b) {
            System.out.println("Value:"+ i + " - Different values");
        } else {
            System.out.println("Value"+ i + " Same values");
        }
    }

Alguma parte da saída do console:

Value:124 - Same values
Value:125 - Same values
Value:126 - Same values
Value:127 - Same values
Value:128 - Different values
Value:129 - Different values
Value:130 - Different values
Value:131 - Different values
Value:132 - Different values

Obrigado!

24
gokhansari

Confira o código fonte do Integer . Você pode ver o cache de valores lá.

O cache só acontece se você usar Integer.valueOf(int), não se você usar new Integer(int). A autoboxing usada por você usa Integer.valueOf

De acordo com o JLS , você pode sempre contar com o fato de que para valores entre -128 e 127, você obtém os objetos Integer idênticos após o autoboxing, e em algumas implementações você pode obter objetos idênticos mesmo para valores maiores valores.

Na verdade, no Java 7 (e penso em versões mais recentes do Java 6), o implementation da classe IntegerCache foi alterado, e o limite superior não é mais codificado, mas é configurável através da propriedade "Java. lang.Integer.IntegerCache.high ", portanto, se você executar seu programa com o parâmetro VM -Djava.lang.Integer.IntegerCache.high=1000, obterá" Same values ​​"para todos os valores.

Mas o JLS ainda garante apenas até 127:

Idealmente, encaixotar um dado valor primitivo p, sempre produziria uma referência idêntica. Na prática, isso pode não ser viável usando as técnicas de implementação existentes. As regras acima são um compromisso pragmático. A cláusula final acima requer que certos valores comuns sejam sempre encaixados em objetos indistinguíveis. A implementação pode armazenar em cache, preguiçosamente ou ansiosamente.

Para outros valores, essa formulação não admite nenhuma suposição sobre a identidade dos valores na caixa da parte do programador. Isso permitiria (mas não exigiria) o compartilhamento de algumas ou todas essas referências.

Isso garante que, na maioria dos casos comuns, o comportamento será o desejado, sem impor uma penalidade de desempenho indevida, especialmente em dispositivos pequenos. Implementações com menos memória limitada podem, por exemplo, armazenar em cache todos os caracteres e curtos, assim como números inteiros e longos no intervalo de -32K a + 32K. 

21
lbalazscs

De acordo com as especificações da linguagem Java: 

Se o valor p sendo encaixotado for verdadeiro, falso, um byte, um caractere no intervalo \U00007 a\u007f ou um int ou um número curto entre -128 e 127, então Deixe r1 e r2 são os resultados de quaisquer duas conversões de boxe de p. É sempre o caso que r1 == r2.

Conversões de Boxe JLS

Consulte este artigo para obter mais informações sobre caching int

6
Denis Rosca

Integer é uma classe de wrapper para int.

Integer != Integer compara a referência real do objeto, onde int != int compara os valores.

Como já foi dito, os valores -128 a 127 são armazenados em cache, então os mesmos objetos são retornados para eles.

Se fora desse intervalo, objetos separados serão criados para que a referência seja diferente.

Para fixar isso:

  • Faça os tipos int ou
  • Transmita os tipos para int ou
  • Use .equals()
6
Dukeling

O objeto Integer possui um mecanismo de cache interno:

private static class IntegerCache {
    static final int high;
    static final Integer cache[];

    static {
        final int low = -128;

        // high value may be configured by property
        int h = 127;
        if (integerCacheHighPropValue != null) {
            // Use Long.decode here to avoid invoking methods that
            // require Integer's autoboxing cache to be initialized
            int i = Long.decode(integerCacheHighPropValue).intValue();
            i = Math.max(i, 127);
            // Maximum array size is Integer.MAX_VALUE
            h = Math.min(i, Integer.MAX_VALUE - -low);
        }
        high = h;

        cache = new Integer[(high - low) + 1];
        int j = low;
        for(int k = 0; k < cache.length; k++)
            cache[k] = new Integer(j++);
    }

    private IntegerCache() {}
}

Veja também o método valueOf:

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

É por isso que você deve usar valueOf em vez de new Integer. A autoboxing usa esse cache.

Veja também este post: https://effective-Java.com/2010/01/Java-performance-tuning-with-maximizing-integer-valueofint/

Usar == não é uma boa ideia, use equals para comparar os valores.

3
Christophe Roussy

Use .equals() em vez de ==.

Valores inteiros são armazenados em cache apenas para números entre -127 e 128, porque são usados ​​com mais freqüência.

if (a.equals(b)) { ... }
2
Doorknob

Dependendo de como você obtém suas instâncias Integer, pode não funcionar para qualquer valor:

System.out.println(new Integer(1) == new Integer(1));

impressões

false

Isso ocorre porque o operador == aplicado a operandos de referência não tem nada a ver com o valor que esses operandos representam.

1
Marko Topolnik

É porque a lógica de implementação de classe Integer. Ele preparou objetos para números até 128. Você pode fazer checkout http://grepcode.com/file/repository.grepcode.com/Java/root/jdk/openjdk/6-b14/Java/lang/Integer.Java source of open-jdk por exemplo (procure pelo cache []).
Basicamente, os objetos não devem ser comparados usando ==, com uma exceção para Enums.

0
sandrstar