This is the 15th day of my participation in the August Text Challenge.More challenges in August
The interview questions
First, a common interview question: What does this code output when run?
When the above code is run, it will eventually print false and true; Why is that?
If i3 and i4 are two different objects, it should also return false. Let’s go down slowly
Integer cache mechanism
Let’s take a look at his source code.
When Integer I =128; ValueOf (int I) =new Integer(128); valueOf(int I);
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
/ / packing
return new Integer(i);
}
Copy the code
As you can see from the source code above, before boxing, an if statement is executed. This if statement determines whether the incoming value is in the cache. If it is in the cache, it returns the value directly.
//Integer wrapper class cache source code
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(a) {}}Copy the code
Integer cache ranges from -128 to 127, so the process is as follows:
If i3==i4 is in the cache pool, it will be true. If i3==i4 is in the cache pool, it will be true. For objects that are not in the cache, a new space will be opened in the heap to store objects, so the == comparison will return different addresses.
Other wrapper class caching mechanisms
In addition to Integer, other wrapper classes also use caching techniques;
Long
Cache range: -128 to 127
public static Long valueOf(long l) {
final int offset = 128;
if (l >= -128 && l <= 127) { // will cache
return LongCache.cache[(int)l + offset];
}
return new Long(l);
}
private static class LongCache {
private LongCache(a){}
static final Long cache[] = new Long[-(-128) + 127 + 1];
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Long(i - 128); }}Copy the code
Byte
Cache range -128 127 (byte range: a byte is 8 bits, so the value range is **-2^7 2^7-1**)
public static Byte valueOf(byte b) {
final int offset = 128;
return ByteCache.cache[(int)b + offset];
}
private static class ByteCache {
private ByteCache(a){}
static final Byte cache[] = new Byte[-(-128) + 127 + 1];
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Byte((byte)(i - 128)); }}Copy the code
Character
Cache range 0 to 127 (ASCII code range)
public static Character valueOf(char c) {
if (c <= 127) { // must cache
return CharacterCache.cache[(int)c];
}
return new Character(c);
}
private static class CharacterCache {
private CharacterCache(a){}
static final Character cache[] = new Character[127 + 1];
static {
for (int i = 0; i < cache.length; i++)
cache[i] = new Character((char)i); }}Copy the code
Short
Cache range: -128 to 127
public static Short valueOf(short s) {
final int offset = 128;
int sAsInt = s;
if (sAsInt >= -128 && sAsInt <= 127) { // must cache
return ShortCache.cache[sAsInt + offset];
}
return new Short(s);
}
private static class ShortCache {
private ShortCache(a){}
static final Short cache[] = new Short[-(-128) + 127 + 1];
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Short((short)(i - 128)); }}Copy the code
Boolean
Cache range true false It sets only two static variables to act as caches
public static final Boolean TRUE = new Boolean(true);
public static final Boolean FALSE = new Boolean(false);
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}
Copy the code
advice
It is recommended to override equals() when wrapping classes to compare whether data is the same.