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