Java Detailed explanation of packing and unpacking

  • 2021-11-01 03:07:35
  • OfStack

Directory packing and unpacking = = null summary

Packing

Each of the 8 basic types has a corresponding class:

基本类型
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean

Except that the last two Character and Boolean classes are derived from Object, the remaining six are inherited from Number classes.

These classes are called wrappers (wrapper), and once an object wrapper is constructed, it is not allowed to change the value of the wrapper in it. At the same time, the object wrapper class is final decorated, so it is impossible to define subclasses that inherit them.

Sometimes it is necessary to convert a basic type to an object, such as defining an integer list. The type parameters in angle brackets are not allowed to be basic types, that is, they are not allowed to be written as ArrayList < int > You need the Integer wrapper class, and you can declare an array list of Integer objects, ArrayList < Integer > .

And for the convenience of adding elements of int type to ArrayList < Integer > The following statement will automatically box


list.add(8);

That is, automatically converted to:


list.add(Integer.valueof(8));

Another example is Integer num=8; It is also automatically boxed and will be converted into Integer num=Integer.valueOf(8);, When a primitive type is assigned to the corresponding class, automatic boxing is triggered.

However, because boxing creates objects, frequent boxing will consume a lot of memory and affect performance, so boxing should be avoided as much as possible.

Unpacking

Similarly, the process of converting a class to its corresponding base type is called unpacking, such as the Integer type variable num above, int num2=num; Automatic unpacking will be triggered and automatically converted to int num2=num.intValue(); .

There are also automatic packing and unpacking in arithmetic expressions, such as:


Integer n=6;
n++;
n-=2;

The compiler will automatically insert an object unpacking instruction, then perform self-increment calculation, and finally box the result.

Note that boxing and unpacking are approved by the compiler, not the virtual machine. When the compiler generates the bytecode of the class, it inserts the necessary method calls, while the virtual machine only executes these bytecodes.

Using a numeric object wrapper can prevent some basic methods from being in the wrapper, such as parseInt() Method converts a numeric string to a numeric value, parseInt() Is a static method, which has nothing to do with the Integer class object here, but the Integer class is a good place to put this method.

And our unpacking is nothing more than automatically calling the methods placed in the class, such as intValue() And valueOf() Wait.

==

Look at it first Integer.valueOf() Function source code, you will know the pit of = =.


public static Integer valueOf(int i) {
	return  i >= 128 || i < -128 ? new Integer(i) : SMALL_VALUES[i + 128];
	}

It will first determine the size of i i i: if i > = 128 i < − 128 i > =128||i < -128 i > = 128i < -128, create an Integer object, otherwise execute SMALL_VALUES [i + 128] and navigate to SMALL_VALUES:


private static final Integer[] SMALL_VALUES = new Integer[256];

It is a static Integer array object that has been created, which means that when i i i is in the range of [-128, 128) [-128, 128) [-128, 128), no new object is created, otherwise new objects will be created, which is why boxing creates objects and consumes memory.

(Insert anti-climbing information) Blogger CSDN Address: https://wzlodq.blog.csdn.net/

For example, the following = = judgment:


    public static void main(String[] args) {
        Integer i1=88;
        Integer i2=88;
        Integer i3=666;
        Integer i4=666;
        System.out.println(i1==i2);//true
        System.out.println(i3==i4);//false
    }

= = is to determine whether the memory addresses of two objects are equal. Obviously, 88 is in the interval (-128, 128), pointing directly to the same created array, while 666 will recreate the new object.

Same boolean, byte, char < 128; When shot and int are between [-128, 127], they will be wrapped in a fixed object, and the comparison result 1 will be established. Otherwise, a new object will be created, and the comparison result will not be established.

In this way, we can know whether to unpack or pack automatically when mixing, such as:


Integer n=666;
int m=666;
System.out.println(n==m);//true

If it is n automatic unpacking, it points to the same address of constant pool, and the result is true; If it is m auto-boxing, not in the range of the interval, and a new object is created, the result is false. The answer is n automatic unpacking.

Another example is:


Integer x=100;
int y=200;
Long z=300l;
System.out.println(x+y==z);//true
System.out.println(z.equals(x+y));//false

If x, y and z unpack automatically, they point to the same address of constant pool, = = result true; If x, y are unpacked and boxed into Long, which is not in the interval range, create a new object, = = the result is false. The answer is to unpack.

Then why does equals output false? Because equals not only has the same comparison value, but also compares data types. Obviously, they are int and long after unpacking, so it is judged as false.

null

Since the wrapper class reference can be null, auto-boxing may throw 1 NullPointerException Exceptions, such as:


Integer n=null;
int m=n;

In addition, if the Integer and Double types are mixed in a conditional expression, the Integer value is unpacked, promoted to Double, and then boxed to Double:


Integer n=6;
Double m=8.0;
System.out.println(true?n:m); //6.0

Summarize

This article is here, I hope to give you help, but also hope that you can pay more attention to this site more content!


Related articles: