El extraño problema del juicio == de dos objetos Integer en Java debido al boxeo automático

Integer es una clase contenedora de int. Dado que es una clase, cuando se compara una variable de tipo Integer ==, es para juzgar si las direcciones referenciadas por dos objetos son iguales.
Por lo tanto, el valor de retorno del siguiente código es falso.

public static void main(String[] args) {
    
    
        Integer i1 = new Integer(1);
        Integer i2 = new Integer(1);
        System.out.println(i1 == i2);//false
    }

Esto es más fácil de entender, porque cada nueva operación se aplicará a un nuevo objeto en el espacio del montón. Sus direcciones deben ser diferentes.
Pero, ¿qué pasa con el resultado del siguiente código?

public static void main(String[] args) {
    
    
        Integer i1 = 1;
        Integer i2 = 1;
        System.out.println(i1 == i2);//true
    }

El resultado de este código resultó ser Verdadero.
1 es un tipo int, se incluirá automáticamente en un Integer, que es equivalente a

public static void main(String[] args) {
    
    
        Integer i1 = Integer.valueOf(1);
        Integer i2 = Integer.valueOf(1);
        System.out.println(i1 == i2);//true
    }

Pero esto no parece explicar por qué las direcciones a las que hacen referencia i1 e i2 son las mismas.
No te preocupes y mira hacia abajo

public static void main(String[] args) {
    
    
        //Integer i1 = Integer.valueOf(128);
        //Integer i2 = Integer.valueOf(128);
        Integer i1 = 128;
        Integer i2 = 128;
        System.out.println(i1 == i2);//false
    }

¡qué! ? El valor de retorno de este código resultó ser Falso.
Entonces, ¿qué está causando esto?
En primer lugar, sabemos que cuando se asigna int a Integer, se incluirá automáticamente en Integer
, es decir, las siguientes dos líneas de código son equivalentes

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

Luego abrimos el código fuente de Integer.valueOf ()

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

¿Qué es IntegerCache.low entre ellos?
Inserte la descripción de la imagen aquí

En este punto, se revela el misterio. Resulta que Integer ya ha almacenado en caché los números de -128 a 127. Si llamamos al método Integer.valueOf (), determinaremos si el parámetro pasado está dentro de este rango. Si es así, devuelve el objeto Integer almacenado en caché.
Otras clases de empaquetado también tienen mecanismos de almacenamiento en caché similares.
Por lo tanto, cuando juzgamos si las clases de empaquetado son iguales, es mejor usar el método equals () en lugar de == (Por supuesto, el tipo booleano no importa, porque solo tiene dos posibilidades, y estas dos ya se han almacenado en caché )

Supongo que te gusta

Origin blog.csdn.net/qq_30033509/article/details/115052402
Recomendado
Clasificación