問題:
- 同樣為數(shù)字 100 為什么結(jié)果有時(shí)返回
false,有時(shí)返回true,而用同樣的方法再使用 200,卻帶來不同的結(jié)果。具體看代碼及運(yùn)行結(jié)果。
public class Main {
public static void main(String[] args) {
Integer n1=new Integer(100);
Integer n2=new Integer(100);
System.out.println(n1==n2);
Integer n3=100; // 自動(dòng)裝箱
Integer n4=100;
System.out.println(n3==n4);
Integer n5=200; // 自動(dòng)裝箱
Integer n6=200;
System.out.println(n5==n6);
}
}
- 結(jié)果:

原因:
- Java 預(yù)先創(chuàng)建了 256 個(gè)常用的整數(shù)包裝類型對(duì)象。(類似字符串中的字符串池,只是這個(gè)池中已經(jīng)有內(nèi)容了)
- 在實(shí)際應(yīng)用當(dāng)中,對(duì)已創(chuàng)建的對(duì)象進(jìn)行復(fù)用。
- 緩存區(qū)數(shù)組 [-128, 127]
分析:
- n1、n2 比較:屬于兩個(gè)對(duì)象,存儲(chǔ)的地址不同,所以不相等返回 false。
- n3、n4 和 n5、n6 通過自動(dòng)裝箱創(chuàng)建,但比較結(jié)果不同
- 上面的代碼可以寫成:
public class Main {
public static void main(String[] args) {
Integer n1=new Integer(100);
Integer n2=new Integer(100);
System.out.println(n1==n2);
// 自動(dòng)裝箱,Integer.valueOf() 為隱藏代碼
Integer n3=Integer.valueOf(100);
Integer n4=Integer.valueOf(100);
System.out.println(n3==n4);
// 自動(dòng)裝箱,Integer.valueOf() 為隱藏代碼
Integer n5=Integer.valueOf(200);
Integer n6=Integer.valueOf(200);
System.out.println(n5==n6);
}
}
- 查看
valueOf()源碼:
@IntrinsicCandidate
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
- 發(fā)現(xiàn):
valueOf(int i)方法中的參數(shù)值在IntegerCache.low與IntegerCache.high之間時(shí),會(huì)返回?cái)?shù)組IntegerCache.cache[]中的值。 - 查看
IntegerCache類的源碼:
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer[] cache;
static Integer[] archivedCache;
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
h = Math.max(parseInt(integerCacheHighPropValue), 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(h, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
// Load IntegerCache.archivedCache from archive, if possible
CDS.initializeFromArchive(IntegerCache.class);
int size = (high - low) + 1;
// Use the archived cache if it exists and is large enough
if (archivedCache == null || size > archivedCache.length) {
Integer[] c = new Integer[size];
int j = low;
for(int i = 0; i < c.length; i++) {
c[i] = new Integer(j++);
}
archivedCache = c;
}
cache = archivedCache;
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
- 從源碼中可以看出
IntegerCache.low==-128、IntegerCache.high==127,同時(shí)可以看出,數(shù)組cache[]大小為 256,存放的元素為{-128,-127,…,126,127}。 - 因?yàn)?100 在
IntegerCache.low~IntegerCache.high之間,所以返回的是數(shù)組cache[]中的元素,所以在比較 n3 與 n4 時(shí),兩者指向的為同一元素,同一地址,而 200 并不在上面的范圍中,所以返回new Interger(200)。 - 相當(dāng)于
public class Main{
public static void main(String[] args) {
Integer a[]={100};
Integer n3=a[0];
Integer n4=a[0];
System.out.println(n3==n4);
Integer n5=new Integer(200);
Integer n6=new Integer(200);
System.out.println(n5==n6);
}
}