Pergunta

class D {
    public static void main(String args[]) {
        Integer b2=128;
        Integer b3=128;
        System.out.println(b2==b3);
    }
}

Output:

false

class D {
    public static void main(String args[]) {
        Integer b2=127;
        Integer b3=127;
        System.out.println(b2==b3);
    }
}

Output:

true

Nota:. Números entre -128 e 127 são verdadeiras

Foi útil?

Solução

Quando você compila um literal número em Java e atribuí-lo a um Integer (I capital), os emite compilador:

Integer b2 =Integer.valueOf(127)

Esta linha de código também é gerado quando você usa autoboxing.

valueOf é implementado de tal forma que certos números são "agrupados", e retorna a mesma instância para valores menores do que 128.

A partir do código-fonte java 1.6, linha 621:

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

O valor da high pode ser configurado para outro valor, com a propriedade do sistema.

-Djava.lang.Integer.IntegerCache.high = 999

Se você executar o seu programa com que a propriedade do sistema, ele irá imprimir verdade!

A conclusão óbvia: nunca confiar em duas referências serem idênticos, sempre compará-los com o método .equals()

.

Assim b2.equals(b3) irá imprimir verdadeiro para todos os valores logicamente iguais de B2, B3.

Note que o cache Integer não está lá por motivos de desempenho, mas sim em conformidade com o JLS, seção 5.1.7 ; identidade do objeto deve ser dada para valores -128 a 127, inclusive.

Integer # valueOf (int) também documenta esse comportamento:

este método é susceptível de produzir espaço e tempo significativamente melhor desempenho pelo cache valores frequentemente solicitados. Este método será sempre valores de cache na faixa de -128 a 127, inclusive, e pode armazenar em cache outros valores fora desta faixa.

Outras dicas

Autoboxing caches -128 a 127. Isso é especificado nas JLS ( 5.1.7 ).

Se o valor p ser encaixotado é verdadeiro, falso, um byte, um char na faixa \ u0000 para \ u007f, ou um int ou short número entre -128 e 127, em seguida, deixar R1 e R2 ser os resultados de quaisquer duas conversões de boxe de p. É sempre o caso que R1 == r2.

Uma regra simples para lembrar quando se lida com objetos é -. Uso .equals se você quiser verificar se os dois objetos são "iguais", o uso == quando você quer ver se eles apontam para a mesma instância

Usando tipos de dados primitivos, ints, produziria verdade em ambos os casos, a saída esperada.

No entanto, desde que você está usando Integer objetos o operador == tem um significado diferente.

No contexto de objetos, == verifica se as variáveis ??se referem ao mesmo objeto de referência.

Para comparar o valor dos objetos que você deve usar o método equals () Por exemplo.

 b2.equals(b1)

que indicará se b2 é inferior a b1, maior que, ou igual a (verifique o API para mais detalhes)

É otimização de memória em Java relacionados.

Para economizar memória, Java 'reutilizações' tudo o wrapper objetos valores cujas cair nos seguintes intervalos:

Todos os valores booleanos (verdadeiro e falso)

Os valores Todos Byte

Todos os valores de caracteres de \ u0000 para \ u007f (ou seja, de 0 a 127 em decimal)

Os valores Todos curto e inteiro de -128 a 127.

Tenha um olhar para o Integer.java, se o valor estiver entre -128 e 127, ele irá utilizar a piscina em cache, então (Integer) 1 == (Integer) 1 enquanto (Integer) 222 != (Integer) 222

 /**
 * Returns an {@code Integer} instance representing the specified
 * {@code int} value.  If a new {@code Integer} instance is not
 * required, this method should generally be used in preference to
 * the constructor {@link #Integer(int)}, as this method is likely
 * to yield significantly better space and time performance by
 * caching frequently requested values.
 *
 * This method will always cache values in the range -128 to 127,
 * inclusive, and may cache other values outside of this range.
 *
 * @param  i an {@code int} value.
 * @return an {@code Integer} instance representing {@code i}.
 * @since  1.5
 */
public static Integer valueOf(int i) {
    assert IntegerCache.high >= 127;
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}       

Eu escrevi o seguinte como este problema não é apenas específico para Integer. Minha conclusão é que mais frequentemente se você usar a API incorretamente, você peitoril ver o comportamento incorreto. Usá-lo corretamente e você deve ver o comportamento correto:

public static void main (String[] args) {
    Byte b1=127;
    Byte b2=127;

    Short s1=127; //incorrect should use Byte
    Short s2=127; //incorrect should use Byte
    Short s3=128;
    Short s4=128;

    Integer i1=127; //incorrect should use Byte
    Integer i2=127; //incorrect should use Byte
    Integer i3=128;
    Integer i4=128;

    Integer i5=32767; //incorrect should use Short
    Integer i6=32767; //incorrect should use Short

    Long l1=127L;           //incorrect should use Byte
    Long l2=127L;           //incorrect should use Byte
    Long l3=13267L;         //incorrect should use Short
    Long l4=32767L;         //incorrect should use Short
    Long l5=2147483647L;    //incorrect should use Integer 
    Long l6=2147483647L;    //incorrect should use Integer
    Long l7=2147483648L;
    Long l8=2147483648L;

    System.out.print(b1==b2); //true  (incorrect) Used API correctly
    System.out.print(s1==s2); //true  (incorrect) Used API incorrectly
    System.out.print(i1==i2); //true  (incorrect) Used API incorrectly
    System.out.print(l1==l2); //true  (incorrect) Used API incorrectly

    System.out.print(s3==s4); //false (correct) Used API correctly
    System.out.print(i3==i4); //false (correct) Used API correctly
    System.out.print(i5==i6); //false (correct) Used API correctly
    System.out.print(l3==l4); //false (correct) Used API correctly
    System.out.print(l7==l8); //false (correct) Used API correctly
    System.out.print(l5==l6); //false (correct) Used API incorrectly

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