A atribuição direta de um literal int para uma referência Integer é um exemplo de boxing automático, em que o valor literal para o código de conversão de objeto é tratado pelo compilador.
Portanto, durante a fase de compilação, o compilador converte Integer a = 1000, b = 1000;
para Integer a = Integer.valueOf(1000), b = Integer.valueOf(1000);
.
Portanto, é o Integer.valueOf()
método que realmente nos dá os objetos inteiros, e se olharmos o código-fonte do Integer.valueOf()
método, podemos ver claramente que o método armazena em cache os objetos inteiros na faixa de -128 a 127 (inclusive).
/**
*
* 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) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
Portanto, em vez de criar e retornar novos objetos inteiros, Integer.valueOf()
o método retorna objetos inteiros do interno IntegerCache
se o literal int passado for maior que -128 e menor que 127.
Java armazena em cache esses objetos inteiros porque esse intervalo de inteiros é muito usado na programação do dia a dia, o que indiretamente economiza alguma memória.
O cache é inicializado no primeiro uso quando a classe é carregada na memória por causa do bloco estático. O intervalo máximo do cache pode ser controlado pela -XX:AutoBoxCacheMax
opção JVM.
Este comportamento de armazenamento em cache não é aplicável apenas a objetos Integer, semelhante a Integer.IntegerCache que também temos ByteCache, ShortCache, LongCache, CharacterCache
para Byte, Short, Long, Character
respectivamente.
Você pode ler mais em meu artigo Java Integer Cache - Why Integer.valueOf (127) == Integer.valueOf (127) Is True .