To understand what 128 traps in java are, we need to look at the following code:
public class Demo { public static void main(String [] args) { Integer a = 127; Integer b = 127; System.out.println(a==b); } }
After running, it is found that the result is true.
However, if we let the value of two variables be 128, we will execute this code again:
public class Demo { public static void main(String [] args) { Integer c = 128; Integer d = 128; System.out.println(c==d); } }
You will find that the output is false.
The question is, why do 127 and 128 differ by only 1, but the output results are very different?
This involves 128 traps in java. Before understanding its principle in detail, let's first understand the automatic unpacking and packing of java:
Packing: convert basic type data into corresponding packing class objects.
The corresponding code is
Integer a = Integer.valueOf(127);
Unpacking: convert packaging objects into corresponding basic data type data.
Code is
int value = a.intValue();
Auto packing: a basic type variable can be directly assigned to the corresponding packing type variable.
Integer a = 127;
Automatic unpacking: allows you to directly assign packaging objects to corresponding basic data type variables.
Integer a = new Integer(127); int b = a;
When assigning values to a and b above, the Java compiler will automatically box them, that is, call the Integer.valueOf() method.
Let's look at the source code of the valueOf() method:
public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
In the source code, we can find that if I > = integercache.low & & I < = integercache.high, an Integer object that already exists in the specified array is returned, otherwise a new object is returned.
Because = = compares the address of the object, when the value assigned to a or b is not within this range, the comparison is two different objects with the same value, so the results will not be equal.
From this, we can see the original code of the IntegerCache class:
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() {} }
As can be seen from the above, IntegerCache.low = -128, IntegerCache.high = 127.
Javadoc describes in detail that this class is used to implement cache support and support the automatic boxing process between - 128 and 127. The maximum value of 127 can be modified through the JVM startup parameter - XX:AutoBoxCacheMax=size. Caching is implemented through a for loop. Create as many integers as possible from small to large and store them in an Integer array called cache. This cache is initialized when the Integer class is first used. Later, you can use the instance objects contained in the cache to improve performance and save memory.
In short, in the valueOf() side of Integet, the values between - 128-127 are stored in a catch array, which is equivalent to a cache. When we perform automatic boxing between - 128-127, we directly return the address of the value in memory, so the values between - 128-127 are compared with = =. Numbers that are not in this range need to open up a new memory space, so they are not equal.