with - java integer equals integer




Por que== comparações com Integer.valueOf(String) fornecem resultados diferentes para 127 e 128? (4)

A classe Integer possui um cache estático, que armazena 256 objetos Integer especiais - um para cada valor entre -128 e 127. Com isso em mente, considere a diferença entre esses três.

new Integer(123);

Isso (obviamente) faz um novo objeto Integer .

Integer.parseInt("123");

Isso retorna um valor primitivo int após analisar a String .

Integer.valueOf("123");

Isso é mais complexo que os outros. Começa analisando a String . Então, se o valor estiver entre -128 e 127, ele retornará o objeto correspondente do cache estático. Se o valor estiver fora desse intervalo, ele invocará o new Integer() e passará o valor para que você obtenha um novo objeto.

Agora, considere as três expressões na questão.

Integer.valueOf("127")==Integer.valueOf("127");

Isso retorna true, porque o Integer cujo valor é 127, é recuperado duas vezes do cache estático e comparado a ele mesmo. Há apenas um objeto Integer envolvido, então isso retorna true .

Integer.valueOf("128")==Integer.valueOf("128");

Isso retorna false , porque 128 não está no cache estático. Então, um novo Integer é criado para cada lado da igualdade. Como existem dois objetos Integer diferentes, e == para objetos somente retorna true se ambos os lados forem exatamente o mesmo objeto, isso será false .

Integer.parseInt("128")==Integer.valueOf("128");

Isso é comparar o valor int primitivo 128 à esquerda, com um objeto Integer recém-criado à direita. Mas como não faz sentido comparar um int com um Integer , o Java desmarcará automaticamente o Integer antes de fazer a comparação; então você acaba comparando um int com um int . Como o primitivo 128 é igual a si mesmo, isso retorna true .

Não tenho ideia de por que essas linhas de código retornam valores diferentes:

System.out.println(Integer.valueOf("127")==Integer.valueOf("127"));
System.out.println(Integer.valueOf("128")==Integer.valueOf("128"));
System.out.println(Integer.parseInt("128")==Integer.valueOf("128"));

A saída é:

true
false
true

Por que o primeiro retorna true e o segundo retorna false ? Existe algo diferente que eu não sei entre 127 e 128 ? (Claro que eu sei que 127 < 128 .)

Além disso, por que o terceiro retorna true ?

Eu li a resposta desta pergunta , mas ainda não entendi como ela pode retornar true , e porque o código na segunda linha retorna false .


Cópias de objetos inteiros entre -128 e 127 de 256 Integer

Você não deve comparar referências de objetos com == ou ! = . Você deveria usar . equals (..) em vez disso, ou melhor - use o int primitivo em vez de Integer.

parseInt : Analisa o argumento de string como um inteiro decimal com sinal. Os caracteres na string devem ser todos dígitos decimais, exceto que o primeiro caractere pode ser um sinal ASCII menos '-' ('\ u002D') para indicar um valor negativo. O valor inteiro resultante é retornado, exatamente como se o argumento e a raiz 10 fossem dados como argumentos para o método parseInt (java.lang.String, int).

valueOf Retorna um objeto Integer mantendo o valor extraído da String especificada quando analisado com a raiz dada pelo segundo argumento. O primeiro argumento é interpretado como representando um inteiro assinado no radical especificado pelo segundo argumento, exatamente como se os argumentos fossem dados ao método parseInt (java.lang.String, int). O resultado é um objeto Integer que representa o valor inteiro especificado pela string.

equivalente a

new Integer(Integer.parseInt(s, radix))

radix - a raiz a ser usada na interpretação de

então se você for igual Integer.valueOf() para o inteiro entre

-128 a 127 retorna verdadeiro em sua condição

por lesser than -128 e greater than 127 dá false


Há uma diferença marcante aqui.

valueOf está retornando um objeto Integer , que pode ter seus valores armazenados em cache entre -128 e 127. É por isso que o primeiro valor retorna true - é armazenado em cache - e o segundo valor retorna false - 128 não é um valor em cache, então você obtendo duas instâncias Integer separadas.

É importante observar que você está comparando referências com Integer#valueOf e, se estiver comparando um valor maior do que o cache suporta, ele não será avaliado como true , mesmo se os valores analisados ​​forem equivalentes (caso em questão: Integer.valueOf(128) == Integer.valueOf(128) ). Você deve usar equals() vez disso.

parseInt está retornando um int primitivo. É por isso que o terceiro valor retorna true - 128 == 128 é avaliado e é claro, é true .

Agora, um bom bocado acontece para tornar o terceiro resultado true :

  • Uma conversão de unboxing ocorre com relação ao operador de equivalência que você está usando e aos tipos de dado que você tem - a saber, int e Integer . Você está recebendo um Integer de valueOf no lado direito, é claro.

  • Após a conversão, você está comparando dois valores int primitivos. A comparação acontece exatamente como você esperaria em relação aos primitivos, então você acaba comparando 128 e 128 .


Para complementar as respostas dadas, também tome nota do seguinte:

public class Test { 
    public static void main(String... args) { 
        Integer a = new Integer(129);
        Integer b = new Integer(129);
        System.out.println(a == b);
    }
}

Este código também será impresso: false

Como o usuário Jay afirmou em um comentário para a resposta aceita, cuidado deve ser tomado ao usar o operador == em objetos, aqui você está verificando se ambas as referências são iguais, o que não é, porque são objetos diferentes, embora eles representem o mesmo valor. Para comparar objetos, você deve usar o método equals :

Integer a = new Integer(128);
Integer b = new Integer(128);
System.out.println(a.equals(b));

Isto irá imprimir: true

Você pode perguntar: Mas então por que a primeira linha foi impressa? . Verificando o código-fonte para o método Integer.valueOf , você pode ver o seguinte:

public static Integer valueOf(String s) throws NumberFormatException {
    return Integer.valueOf(parseInt(s, 10));
}

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);
}

Se o parâmetro for um inteiro entre IntegerCache.low (padrão -128) e IntegerCache.high (calculado em tempo de execução com valor mínimo 127), um objeto pré-alocado (em cache) será retornado. Então, quando você usa 127 como parâmetro, você está recebendo duas referências ao mesmo objeto em cache e ficando true na comparação das referências.







comparison