Have you stepped on the "pit" of the Integer class in Java?

One, the problem

The murder caused by a piece of code

In order to allow the int type method parameter to receive a null value, we usually set it to the int type packaging type Integer. Our story begins here. Let’s look at a piece of code first:

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("失败!");
        }
    }
}

Console output:

成功!
失败!

My God, why the second output failed instead of succeeding! collapse. . . .

Two, cause

guess

We guess it is caused by the Integer class. We know that Integer is a packaging class of the int type. This involves Java's automatic boxing and unboxing. So what is automatic boxing and unboxing?

Automatic boxing and unboxing in Java

Since Java SE5 has provided automatic boxing and unboxing features. Boxing is to automatically convert the basic data type to the wrapper type; unboxing is to automatically convert the wrapper type to the basic data type. As follows:

Integer m = 100; //装箱

int y = m; //拆箱

Low-level implementation of boxing and unboxing

Let's take the Integer class as an example, let's look at a piece of code first:

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

The decompiled bytecode of this code is as follows:

From the content of the bytecode obtained by decompilation, it can be seen that the valueOf(int) method of Integer is automatically called when boxing, and the intValue method of Integer is automatically called when unboxing. Other basic types are similar, interested friends can try it!

Next we need to view the source code of the Integer.valueOf method, let's take a look:

From the above we can see that IntegerCache is used here. Next, let’s take a look at the IntegerCache class. We find that IntegerCache is an internal class of Integer:

We can find from the source code that the original Integer class has its own cache by default, and the cache range is [-128-127] by default. In this way, we can explain the situation of the above example. 10 is in the cache range, so the same object is returned twice, and 128 is not in the cache range, so an Intger object is created each time, which results in two objects Not waiting.

Three, the solution

To solve our above problem, we only need to use the Integer.intValue() method. The modified code is as follows:

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("失败!");
        }
    }
}

Console output:

成功!
成功!

We can see that the answer is consistent with our expected answer

Four, summary

The Integer class comes with a cache by default, which may cause some unimaginable results in some cases, so we need to pay attention when using it!

Well, today we are here. You can think about a question. There are corresponding wrapper classes in 8 basic data types in Java, so do all wrapper classes have internal caches? Welcome everyone to leave a message below! 

                                                               Welcome to pay attention to Xiaoqiang 1024 Lab, and use technology to change the world with Xiaoqiang

Guess you like

Origin blog.csdn.net/u011147339/article/details/109210953