catalogue
preface
If you encounter problems, write it yourself and see the source code.
summary
For example, integer:
Integer a = 11;
The system automatically helps us:
Integer a = Integer.valueOf(11);
int b = a;
The system automatically executes:
int b = a.intValue();
Therefore, we need to pay attention to valueOf and intValue;
Primitive types: byte, short, char, int, long, float, double and boolean
The corresponding are: Byte, Short, Character, Integer, Long, Float, Double, Boolean.
Why unpack and pack?
In order to reduce the creation of objects in java.
Only the double and float auto boxing codes do not use caching, and each time they are new objects. The other six basic types use caching strategies.
The cache policy is used because these cached objects are often used (such as characters and numbers between - 128 and 127), so as to prevent the creation of an instance of this object every time auto boxing.
(PS: because double and float are floating-point, there is no special hot (often used) data)
Character creates cached data whose value is in the range of [0127], and Boolean directly returns True Or False.
Sample code
boolean
Test:
public static void main(String[] args) { boolean i1 = false; Boolean i2 = false; boolean i3 = true; Boolean i4 = true; //true System.out.println(i1 == i2); //true System.out.println(i3 == i4); }
Nothing special.
Because there are only these two cases in boolean in java class, static final has created this thing.
{ /** * The {@code Boolean} object corresponding to the primitive * value {@code true}. */ public static final Boolean TRUE = new Boolean(true); /** * The {@code Boolean} object corresponding to the primitive * value {@code false}. */ public static final Boolean FALSE = new Boolean(false);
Integer
/** * Returns an {@code Integer} instance representing the specified * {@code int} value. If a new {@code Integer} instance is not * required, this method should generally be used in preference to * the constructor {@link #Integer(int)}, as this method is likely * to yield significantly better space and time performance by * caching frequently requested values. * * This method will always cache values in the range -128 to 127, * inclusive, and may cache other values outside of this range. * * @param i an {@code int} value. * @return an {@code Integer} instance representing {@code i}. * @since 1.5 */ 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 above code, there is mainly an IntegerCache and a new 'object is returned.
This code is that if it is between - 128 and 127, we will use the object in the cache instead of giving it a new object.
/** * Cache to support the object identity semantics of autoboxing for values between * -128 and 127 (inclusive) as required by JLS. * * The cache is initialized on first usage. The size of the cache * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option. * During VM initialization, java.lang.Integer.IntegerCache.high property * may be set and saved in the private system properties in the * sun.misc.VM 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() {} }
Maintains a cache array,
Static static method, which is initialized when the class is loaded. cache [], static variables are stored in the constant pool
This class statically initializes an integer IntegerCache. Low to Java lang.Integer. IntegerCache. Integer array of high.
Where Java lang.Integer. IntegerCache. The value range of high is [127~Integer.MAX_VALUE - (-low) -1].
All are put in Integer cache [];
This part is ready when initializing~
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
I have a question, why must the maximum value be read from the configuration?
String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
Maybe this can be configured. It can be larger.
This is my guess.
/** * Returns the value of this {@code Integer} as an * {@code int}. */ public int intValue() { return value; }
Unpacking is to directly return the value in the class, which is relatively simple;
Exercises
public static void main(String[] args) { Integer i1 = 40; Integer i2 = 40; Integer i3 = 0; Integer i4 = new Integer(40); Integer i5 = new Integer(40); Integer i6 = new Integer(0); System.out.println("i1=i2 " + (i1 == i2));//true System.out.println("i1=i2+i3 " + (i1 == i2 + i3));//true System.out.println("i1=i4 " + (i1 == i4));//false System.out.println("i4=i5 " + (i4 == i5));//false System.out.println("i4=i5+i6 " + (i4 == i5 + i6));//true is because there is addition, which is the operation. If the operation is performed, we will compare the values System.out.println("40=i5+i6 " + (40 == i5 + i6));//true Integer i7 = new Integer(115); Integer i8 = new Integer(40); Integer i9 = new Integer(155); System.out.println("155=i5+i6 " + (155 == i7 + i8));//true System.out.println("i9=i5+i6 " + (i9 == i7 + i8));//true }
If there are operations, then the comparison is the value. Remember this.
If new is used = =, the memory address is compared