JDK version: 1.8.0_271
Basic introduction to
Caching mechanisms
Wrapper classes are the encapsulation of basic types in Java. In JDK5, the caching mechanism of wrapper classes is introduced to help save memory. The way to do this is to create a wrapper object that will be used frequently during class initialization. When a wrapper object of a class needs to be used, if the value of the wrapper object is within the scope of the cache, the cached object is returned. Otherwise, a new object is created and returned.
Objects are created using constructors without caching. For example, Integer a = new Integer(123);
Among wrapper classes, Float,Double, the wrapper class for floating-point types, does not implement constant pooling technology.
Basic data type | Packing type | The cache scope |
---|---|---|
byte | Byte | – 128 ~ 127 |
short | Short | – 128 ~ 127 |
int | Integer | – 128 ~ 127 |
long | Long | – 128 ~ 127 |
char | Character | 0 ~ 127 |
boolean | Boolean | true,false |
float | Float | There is no |
double | Double | There is no |
Long cache
The cache initialization source in the Long class looks like this:
Private static class LongCache {private LongCache(){} private static class LongCache(){} Static final Long cache[] = new Long[-(-128) + 127 +1]; static { for(int i = 0; i < cache.length; Cache [I] = new Long(i-128); }}Copy the code
The Integer cache
A slightly different cache and Long Integer, in JDK6 has a maximum of Integer can be used to the JVM startup parameter is set maximum: – Djava. Lang. Integer. IntegerCache. High = XXX
The source code
/** * 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() {} }Copy the code
Use of caching
The cache is used during autoboxing, and the underlying call is to the integer.valueof (int I) method of the enclosing class
The Integer source
/** * 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); }Copy the code
Long source
public static Long valueOf(long l) { final int offset = 128; If (l >= -128 && l <= 127) {return longcache. cache[(int)l + offset]; } return new Long(l); }Copy the code
Other problems
Why is it recommended to use an integer wrapper classvalueOf()
Methods, use lessparseXXX()
Methods?
Because wrapper classes such as Integer and Long have caching mechanisms, the valueOf method will take the value from the cache. If the cache is hit, the resource overhead will be reduced. The parseXXX method does not have this mechanism.
Can the switch statement work on bytes, can the switch statement work on longs, can the switch statement work on strings?
A byte has a storage range smaller than an int and can be implicitly converted to an int, so a switch can be applied to a byte
A long has a storage range larger than an int. It cannot be implicitly converted to an int. It can only be cast, so a switch cannot be applied to a long
Strings were not available before version 1.7, after which switch can be used on strings