验证
运行代码
java
public class Main{
public static void main(String[] args) {
Integer a = 100;
Integer b = 100;
System.out.println(a == b);
Integer c = 200;
Integer d = 200;
System.out.println(c == d);
}
}
运行结果
out
true
false
原因
java
Integer a = 100;
这段代码是自动装箱/拆箱机制,本质上是调用Integer.valueof(100)
给出源码
java
@IntrinsicCandidate
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
可以看到当i的值在IntegerCache.low到IntegerCache.high之间的时候返回缓存池里面的值,否则返回新值,我们再具体看一下IntegerCache的源码。
java
private static final class IntegerCache {
static final int low = -128;
static final int high;
@Stable
static final Integer[] cache;
static Integer[] archivedCache;
static {
int h = 127;
String integerCacheHighPropValue =
VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
h = Math.max(parseInt(integerCacheHighPropValue), 127);
h = Math.min(h, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
}
}
high = h;
CDS.initializeFromArchive(IntegerCache.class);
int size = (high - low) + 1;
if (archivedCache == null || size > archivedCache.length) {
Integer[] c = new Integer[size];
int j = low;
int archivedSize = (archivedCache == null) ? 0 : archivedCache.length;
for (int i = 0; i < archivedSize; i++) {
c[i] = archivedCache[i];
assert j == archivedCache[i];
j++;
}
for (int i = archivedSize; i < size; i++) {
c[i] = new Integer(j++);
}
archivedCache = c;
}
cache = archivedCache;
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
也就是说如果数值在[-128,127]之间,就返回缓存池里面已经存在的对象,否则创建一个新的Integer对象。
上面代码,a和b都是100,在[-128,127]之间,都是缓存池里面的同一个对象,指向同一地址,c和d是200,不在[-128,127]之间,会返回新的,指向不同地址。
面试
在 Java 中,Integer 对象的比较行为受缓存机制影响。对于值在 [-128, 127] 范围内的 Integer,由于缓存池的存在,多个 Integer 实例会指向同一个对象,导致 == 比较为 true。而超出此范围的 Integer 则会返回新的对象,因此 == 比较为 false。