java packing and unpacking

Keywords: Java jvm

java packing and unpacking

Packing

Basic data type = > wrapper class

For example, int = > integer

Unpacking

Wrapper class = > basic data type

For example, integer = > int

Why are there basic data types?

Because in java, a new object is stored in the heap. For the data types we often operate on, creating an object each time consumes too much resources. Therefore, java provides eight basic data types, which are stored in the stack. It's more convenient to use.

Automatic type conversion
The number of bits in the data type before conversion is lower than that in the data type after conversion.
For example, if the bit number of the short data type is 16 bits, the int type with 32 bits can be automatically converted. Similarly, if the number of bits of the float data type is 32, it can be automatically converted to the 64 bit double type.

Low
byte,short,char—> int —> long—> float —> double
Data type conversion must meet the following rules:
Cannot cast boolean types.
You cannot convert an object type to an object of an unrelated class.
Precision is lost from large to small: casts must be used when converting a large capacity type to a small capacity type.

Basic data type Packaging
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean

Do an experiment

Do a simple experiment, output a variety of cases of packing and unpacking results

 				int i1 = 132;
        Integer i2 = 132;
        System.out.printf("i1 == i2:%15b%n",(i1 == i2));
        System.out.printf("i2.equals(i1):%10b%n",i2.equals(i1));

        Integer i3 = 132;
        Integer i4 = 132;
        System.out.printf("i3 == i4:%15b%n",(i3 == i4));
        System.out.printf("i3.equals(i4):%10b%n",i3.equals(i4));

        Integer i5 = new Integer(132);
        Integer i6 = new Integer(132);
        System.out.printf("i5 == i6:%15b%n",(i5 == i6));
        System.out.printf("i5.equals(i6):%10b%n",i5.equals(i6));

        Integer i7 = 132;
        Integer i8 = new Integer(132);
        System.out.printf("i7 == i8:%15b%n",(i7 == i8));
        System.out.printf("i7.equals(i8):%10b%n",i7.equals(i8));
        System.out.println("-----------------------------");
        int j1 = 32;
        Integer j2 = 32;
        System.out.printf("j1 == j2:%15b%n",(j1 == j2));
        System.out.printf("j2.equals(j1):%10b%n",j2.equals(j1));

        Integer j3 = 32;
        Integer j4 = 32;
        System.out.printf("j3 == j4:%15b%n",(j3 == j4));
        System.out.printf("j3.equals(j4):%10b%n",j3.equals(j4));

        Integer j5 = new Integer(32);
        Integer j6 = new Integer(32);
        System.out.printf("j5 == j6:%15b%n",(j5 == j6));
        System.out.printf("j5.equals(j6):%10b%n",j5.equals(j6));

        Integer j7 = 32;
        Integer j8 = new Integer(32);
        System.out.printf("j7 == j8:%15b%n",(j7 == j8));
        System.out.printf("j7.equals(j8):%10b%n",j7.equals(j8));

result:

i1 == i2:           true
i2.equals(i1):      true
i3 == i4:          false
i3.equals(i4):      true
i5 == i6:          false
i5.equals(i6):      true
i7 == i8:          false
i7.equals(i8):      true
-----------------------------
j1 == j2:           true
j2.equals(j1):      true
j3 == j4:           true
j3.equals(j4):      true
j5 == j6:          false
j5.equals(j6):      true
j7 == j8:          false
j7.equals(j8):      true

It can be found that the equals comparison is true. To explore the reasons, the following is Integer.equals Source code

Here we will talk about the intValue. The source code of this method is very simple, which is to return the basic data type in this object

In short, Integer.equals Is a value comparison, a comparison between int and int

Look at the comparison of = = again

==The essence of is memory address comparison

When Integer == int judges, it will unpack the inger and convert it to the basic data type. This is the comparison between int and int, which turns into the comparison of values

When Integer == Integer, it is the comparison of memory address, or reference

Continue to compare the online and offline segmentation results, you can find that there is a difference between the upper and lower here

				Integer i3 = 132;
        Integer i4 = 132;
        System.out.printf("i3 == i4:%15b%n",(i3 == i4));
        System.out.printf("i3.equals(i4):%10b%n",i3.equals(i4));
        
        Integer j3 = 32;
        Integer j4 = 32;
        System.out.printf("j3 == j4:%15b%n",(j3 == j4));
        System.out.printf("j3.equals(j4):%10b%n",j3.equals(j4));
i3 == i4:          false
i3.equals(i4):      true
----------------------------
j3 == j4:           true
j3.equals(j4):      true

First of all, pay attention here

Integer i3 = 132;
Integer i4 = 132;

The package type is on the left and the basic data type is on the right

Here, Integer will do automatic boxing, and automatically change the basic data type to the packing type

Here Auto boxing will be called automatically Integer.valueOf() method

Keep playing the source code

As you can see, it is not necessary to create a new wrapper type here, but to check whether i is in the cache range first, and then use the objects in the cache

What are the values of low and high?

Direct source

    private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;

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

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {}
    }

You can see that low is fixed to - 127 and high is set to 127 by default. You can use the jvm parameter( java.lang.Integer.IntegerCache.high )Set the value of high

And there's another interesting thing down there

private IntegerCache() {}

Private constructor: private constructor cannot be used outside this class, which means that this class cannot be instantiated with new, which can control the generation of objects.

So i3 and i4 are two wrapper type objects (they have different memory addresses)

Because = = is a memory address comparison

So when i3 == i4 returns, false

Let's look at the part below the dividing line

Here, j3 == j4 returns true

As mentioned above, there is a cache pool inside Integer. Since 32 is in the scope of cache pool, it will return objects in the same cache pool

So, j3 == j4 returns true

Keep looking at this comparison

 				Integer j5 = new Integer(32);
        Integer j6 = new Integer(32);
        System.out.printf("j5 == j6:%15b%n",(j5 == j6));
        System.out.printf("j5.equals(j6):%10b%n",j5.equals(j6));
i5 == i6:          false
i5.equals(i6):      true

It's easy to understand two objects with different addresses and the same value

j5 == j6 is naturally false

Last comparison

				Integer j7 = 32;
        Integer j8 = new Integer(32);
        System.out.printf("j7 == j8:%15b%n",(j7 == j8));
        System.out.printf("j7.equals(j8):%10b%n",j7.equals(j8));
j7 == j8:          false
j7.equals(j8):      true

false is returned here because:

j7 is an instance of auto boxing. The final result is an Integer object in the cache pool with a value of 32,

j8 is a new object

j7 and j8 are two objects with different addresses and the same values

Therefore, false is returned



If there is any mistake, please correct it

Posted by cowboy_x on Mon, 29 Jun 2020 01:40:14 -0700