TL; DR
Java armazena em cache instâncias inteiras em caixa de -128a 127. Como você está usando ==para comparar referências de objetos em vez de valores , apenas os objetos em cache corresponderão. Trabalhe com longvalores primitivos não encaixotados ou use .equals()para comparar seus Longobjetos.
Versão longa (trocadilho intencional)
Por que há problema em comparar a variável longa com valor maior que 127? Se o tipo de dados da variável acima for primitivo (longo), o código funcionará para todos os valores.
Java armazena em cache instâncias de objetos inteiros de -128 a 127 . Dito isto:
- Se você definir como N variáveis longas o valor
127(em cache ), a mesma instância do objeto será apontada por todas as referências. (N variáveis, 1 instância)
- Se você definir como N variáveis longas o valor
128( não armazenado em cache ), você terá uma instância de objeto apontada por cada referência. (N variáveis, N instâncias)
É por isso que:
Long val1 = 127L;
Long val2 = 127L;
System.out.println(val1 == val2);
Long val3 = 128L;
Long val4 = 128L;
System.out.println(val3 == val4);
Produz isto:
verdadeiro
falso
Para o valor 127L , como ambas as referências (val1 e val2) apontam para a mesma instância do objeto na memória (em cache), ele retorna true.
Por outro lado, para o valor 128 , uma vez que não há instância para ele em cache na memória, uma nova é criada para quaisquer novas atribuições para valores em caixa, resultando em duas instâncias diferentes (apontadas por val3 e val4) e retornando falseno comparação entre eles.
Isso acontece apenas porque você está comparando duas Long referências de objeto , não longvalores primitivos, com o ==operador. Se não fosse por esse mecanismo de Cache, essas comparações sempre falhariam, então o verdadeiro problema aqui é comparar os valores em caixa com o ==operador.
Alterar essas variáveis para longtipos primitivos impedirá que isso aconteça, mas caso você precise manter seu código usando Longobjetos, pode fazer essas comparações com segurança com as seguintes abordagens:
System.out.println(val3.equals(val4)); // true
System.out.println(val3.longValue() == val4.longValue()); // true
System.out.println((long)val3 == (long)val4); // true
(A verificação nula adequada é necessária, mesmo para peças fundidas)
IMO , é sempre uma boa idéia manter os métodos .equals () ao lidar com comparações de objetos.
Links de referência:
.longValue().