¿Ha pisado el "pozo" de la clase Integer en Java?

Uno, el problema

El asesinato causado por un código

Para que los parámetros del método del tipo int reciban valores nulos, generalmente lo configuramos en el tipo de empaquetado Integer del tipo int. Nuestra historia comienza aquí. Veamos primero un fragmento de código:

public class Demo {

    public static void main(String[] args) {
        test(10,10);
        test(128,128);
    }
    public static void test(Integer i,Integer j){
        if(i == null || j == null){
            return;
        }
        if(i == j){
            System.out.println("成功!");
        }else {
            System.out.println("失败!");
        }
    }
}

Salida de consola:

成功!
失败!

Dios mío, ¿por qué la segunda salida falló en lugar de tener éxito? colapso. . . .

Dos, porque

adivinar

Suponemos que es causado por la clase Integer. Sabemos que Integer es una clase de empaquetado del tipo int. Esto involucra el boxing y unboxing automático de Java. Entonces, ¿qué es el boxeo y unboxing automático?

Boxeo y unboxing automático en Java

Desde Java SE5 ha proporcionado funciones automáticas de empaquetado y desempaquetado. El boxing es convertir automáticamente el tipo de datos básico al tipo de contenedor; el desempaquetado es convertir automáticamente el tipo de contenedor al tipo de datos básico. Como sigue:

Integer m = 100; //装箱

int y = m; //拆箱

Implementación de bajo nivel de boxeo y unboxing.

Tomemos la clase Integer como ejemplo, primero veamos un fragmento de código:

​​​​​​​public class Case {
    public static void main(String[] args) {
        Integer m = 100;
        int y = m;
    }
}

El bytecode descompilado de este código es el siguiente:

A partir del contenido del bytecode obtenido por descompilación, se puede ver que el método valueOf (int) de Integer se llama automáticamente al boxear, y el método intValue de Integer se llama automáticamente al unboxing. Otros tipos básicos son similares, ¡los amigos interesados ​​pueden probarlo!

A continuación, necesitamos ver el código fuente del método Integer.valueOf, echemos un vistazo:

De lo anterior, podemos ver que IntegerCache se usa aquí. A continuación, echemos un vistazo a la clase IntegerCache. Encontramos que IntegerCache es una clase interna de Integer:

Podemos encontrar en el código fuente que la clase Integer original tiene su propia caché por defecto, y el rango de caché es [-128-127] por defecto. Entonces podemos explicar la situación en el ejemplo anterior. 10 está en el rango de caché, por lo que el mismo objeto se devuelve dos veces, y 128 no está en el rango de caché, por lo que se crea un objeto Intger cada vez, lo que da como resultado dos objetos Sin esperar.

Tres, la solución

Para resolver nuestro problema anterior, solo necesitamos usar el método Integer.intValue (). El código modificado es el siguiente:

public class Demo {

    public static void main(String[] args) {
        test(10,10);
        test(128,128);
    }
    public static void test(Integer i,Integer j){
        if(i == null || j == null){
            return;
        }
        if(i.intValue() == j.intValue()){
            System.out.println("成功!");
        }else {
            System.out.println("失败!");
        }
    }
}

Salida de consola:

成功!
成功!

Podemos ver que la respuesta es consistente con nuestra respuesta esperada

Cuatro, resumen

La clase Integer viene con un caché por defecto, lo que puede causar algunos resultados inimaginables en algunos casos, ¡así que debemos prestar atención al usarlo!

Bien, hoy estamos aquí. Puede pensar en una pregunta. Los 8 tipos de datos básicos en Java tienen clases de empaquetado correspondientes, entonces, ¿todas las clases de empaquetado tienen cachés internos? ¡Bienvenidos a todos a dejar un mensaje a continuación! 

                                                               Bienvenido a prestar atención a Xiaoqiang 1024 Lab y usar la tecnología para cambiar el mundo con Xiaoqiang

Supongo que te gusta

Origin blog.csdn.net/u011147339/article/details/109210953
Recomendado
Clasificación