Integer底層設計
100 == 100為true,1000 == 1000卻為false?
之前也寫過String的==與equals的注意點,這次寫下Integer的底層設計,不妨先執行下下面程式碼:
Integer a = 1000, b = 1000;
System.out.println(a == b);//1
Integer c = 100, d = 100;
System.out.println(c == d);//2
基本知識:我們知道,如果兩個引用指向同一個物件,用 == 表示它們是相等的。如果兩個引用指向不同的物件,用 == 表示它們是不相等的,即使它們的內容相同。
這裡就涉及到Integer底層的IntegerCache.java,它快取了從 - 128 到 127 之間的所有的整數物件。
具體實現就是:當所有的小整數在內部快取,然後當我們宣告類似——
Integer c = 100;
實際做的是
Integer i = Integer.valueOf(100);
而內部valueof實現
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i
return IntegerCache.cache\[i + (-IntegerCache.low)\];
return new Integer(i);
}
如果值的範圍在 - 128 到 127 之間,它就從快取記憶體返回例項,C與D的引用其實都是指向同一物件,所以相同,而不再這個值得a,b就不從快取記憶體放回例項,所以不指向同一物件。
綜上所述:java中,像String,Integer這些不要用==進行比較,因為比較的是引用(基本資料型別除外),應該使用equals,這也符合sonarlint規範。
下面給出快取記憶體的魅力吧!
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
Class cache = Integer.class.getDeclaredClasses()[0]; //1
Field myCache = cache.getDeclaredField("cache"); //2
myCache.setAccessible(true);//3
Integer[] newCache = (Integer[]) myCache.get(cache); //4
newCache[132] = newCache[133]; //5
int a = 2;
int b = a + a;
System.out.printf("%d + %d = %d", a, a, b); // 2 + 2= 5;
}