[Interview preparation] Java basics on automatic boxing and unboxing

Hello, everyone, I am a pig who is dominated by cabbage.

A person who loves to study, sleepless and forgets to eat, is obsessed with the girl's chic, calm and indifferent coding handsome boy.

If you like my text, please follow the public account "Let go of this cabbage and let me come".

Automatic boxing and unboxing

Preface

Recently, I was preparing for future internship interviews and autumn recruits. During the review process, I found that I did not master many things, especially the basics. Many concepts and details were not understood in depth, plus my own. Laziness and procrastination have always had this problem in my heart. In fact, I said a long time ago that I wanted to review, but after a month, I still didn’t take any action. I was still very anxious. What can I do with work?

Of course, this is useless. Let us say goodbye to anxiety and panic, one step at a time, and then we will break the status quo through daily updates, like a bank screw, and get a little knowledge point every day.

If you don't accumulate steps, you can't reach a thousand miles; if you don't accumulate small currents, you can't become a river. Say goodbye to the once anxious yourself and start acting!

Let’s talk about auto-boxing and unboxing in Java today.

I will introduce what, why, and how it is, why it is done, and how to do it. Learn to know why and why.

what

What is auto-boxing and what is auto-unboxing? Once a handsome guy had such a question when coding, how could an Integer suddenly pop up when using int? Recently, when I was learning JVM, I gradually solved the doubts in my fun. Char, byte, short, int, long, float, double, and boolean are called basic data types. Like Character, Byte, Short, Integer, Long, Float, Double, Boolean, and the classes we created such as Person, they are all a class. To talk about data types, they are all reference data types. The former is also called a wrapper type. For example, Integer is a wrapper type of int.

We must clarify this concept in our minds, especially to distinguish int as a type, and Integer is a class. The class contains properties, methods, and so on. In many places they have to be treated separately. For example, basic data types are stored on the stack in the JVM, while object instances are stored on the heap, and the stack is just a reference to this object. Another example is ==. For basic data types, compare their values, and for reference data types, compare the memory address of the object storage.

Having said so much, the main thing is to integrate the knowledge points, learn to understand, learn from other things, and don't memorize it by rote. So much foreshadowing, enter the subject.

Automatic boxing is to automatically convert basic data types into wrapper types;

Automatic unboxing is to automatically convert the wrapper type into a basic data type.

why

We know that in Java, everything is an object. We operate more objects, and the purpose of packaging them into a class is to allow us to better manipulate them. Let’s see how the jdk documentation says

IntegerClass packaging a basic object type intvalue. IntegerObject type comprises a inttype field.

In addition, this class provides several methods can be in inttype and Stringmutual conversion between types, also provides a process intuseful when the type of constants and other methods.

To put it bluntly, there are many methods in it to facilitate our operations. Like ArrayList he stores all objects, and ArrayList<int> is wrong.

how

How do they achieve automatic boxing and unboxing? I'm just learning JVM. For the following code, we use javap to decompile and take a look at the contents of the bytecode file.

public class AutoBoxing {
    
    
    public static void main(String[] args) {
    
    
        Integer a = 1000;
        int b = a + 1;
    }
}

Insert picture description here

We see that the operation of boxing and unboxing is automatically completed during compilation. Boxing calls the Integer.valueOf() method, and unboxing calls the Integer.intValue() method.

If we int b = a + 1; change to Integer b = a + 1; then use the javap command to decompile

Insert picture description here

Looking at the difference between the two screenshots, we found that before performing arithmetic operations, we unboxed first, and then we performed boxing after the arithmetic operations. This shows that the final calculation is to be converted to basic data types . Unexpectedly, there are so many things behind such a small line of code and a plus sign.

Let's use an example to understand valueOf.

public class AutoBoxing {
    
    
    public static void main(String[] args) {
    
    
//        Integer a = 1000;
//        Integer b = a + 1;
        Integer a = 100;
        Integer b = 100;

        Integer c = 200;
        Integer d = 200;

        System.out.println(a == b);
        System.out.println(c == d);

        System.out.println(a.equals(b));
        System.out.println(c.equals(d));

    }
}

At the beginning, hey, 200 is equal to 200, how come the result is false? Then why is 100 equal to 100 established? 200 is not equal to 200, then why is equals established again? Does the little friend also have so many question marks.

Next, we will explore the essence of it in depth. Let's open the source code and take a look at the ValueOf method in Integer.

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

We found that in the conversion process, instead of directly creating an Integer object, it returns the element corresponding to the subscript in the array in the cache class. Then we click the IntegerCache class.

Insert picture description here

cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);

We found through reading the source code that he actually helped us create objects in the range of -128-127 in advance. We can modify the value of 127 through commands. The default is 127, which means that in this range, we have more Created this time, what you get is actually the same object. Just like the thread pool, it has the effect of reuse and improved efficiency. So think about why it is called IntegerCache for a reason.

Okay, then we will understand why 100 == 100 is true and 200 == 200 is false. As mentioned earlier, == compares the value itself for basic data types, and compares the memory address of the object for reference types. In the range of -128 to 127, the same object is used, so the memory address is the same, instead of recreating an object every time in this range, the memory address of the object is definitely different.

Then why the equals below are all true. We click on the equals method

    public boolean equals(Object obj) {
    
    
        if (obj instanceof Integer) {
    
    
            return value == ((Integer)obj).intValue();
        }
        return false;
    }

The first thing to judge is whether it is this type of Integer, instead of returning false directly. Then call the intValue method to unbox it. Let's look at intValue(). It's very simple. Return this value directly.

    public int intValue() {
    
    
        return value;
    }

After unboxing, it is the basic data type. Use = to compare their values, 200 == 200, it must be equal.

Friends, listening to my explanation, is it suddenly clear?

Detailed explanation of other types

Integer we know almost, what about other types?

We can know by reading the source code:

  • Byte, Short, Long are the same as Integer, and the default range is -128 to 127.

  • Character is 0 to 127. Because it has no negative numbers.

  • Float and Double do not have this kind of caching mechanism, because if you think about it, the number of novels is uncertain. There are many, many, many numbers in the middle of 0-1.

  • Boolean is directly represented by two objects, the value is True and the value is False.
    Insert picture description here

Final kill

Finally, we use a question to judge whether we fully grasp the concept.

 public static void main(String[] args) {
    
    
        Integer a = 1;
        Integer b = 2;
        Integer c = 3;
        Integer d = 3;
        Integer e = 321;
        Integer f = 321;
        Long g = 3L;
        Long h = 2L;

        System.out.println(c==d); //true
        System.out.println(e==f); //false
        System.out.println(c==(a+b)); //true
        System.out.println(c.equals(a+b)); //true
        System.out.println(g==(a+b)); //true
        System.out.println(g.equals(a+b)); //false
        System.out.println(g.equals(a+h)); //true

    }

I think after reading this article, it should be easy to solve these problems. The hard part should be the penultimate and the penultimate, unpacking and repacking. Take me as a principle, the calculation is the basic data type, equals is a method in the object, so both sides must be objects.

Take the penultimate distance, a + h, first unboxing. At this time, pay attention to a type conversion. A is int and h is long, so the final type is long, and the final boxing result is Long. The penultimate type of auto-boxing is Integer, which of course is not equal to the Long type.

to sum up

In the process of learning, we must learn to grasp the essence of things in order to remain unchanged and respond to changes. There are many martial arts in the world, and I like Dugu Nine Swords the most. The epee has no edge, and the skill is not working.

Guess you like

Origin blog.csdn.net/weixin_44226263/article/details/112426289