Integer 中你所不知道的
- 2020 年 2 月 10 日
- 筆記
前幾天和我六哥討論技術的時候說到了 Integer,大家可能覺得 Intger 有什麼好說的,不就是 int 嗎,Java 裝箱拆箱機制。那麼現在有這樣一個問題:
System.out.println(new Integer(1) == (new Integer(1))); System.out.println(new Integer(1).equals(new Integer(1))); System.out.println(Integer.valueOf(1) == Integer.valueOf(1)); System.out.println(Integer.valueOf(129) == Integer.valueOf(129));
這四行程式碼分別輸出什麼,為什麼? 答案:false、true、true、false
如果你沒答出來,那麼請繼續往下看吧~
IntegerCache
對,先說這個類,一看名字就知道是 Integer 快取,它是 Integer 的一個靜態內部類。源碼不多,先看程式碼:
private static class IntegerCache { static final int low = -128; static final int high; // 這個值可以在vm屬性配置 static final Integer cache[]; static { ... // 給 high 賦值,從 vm 屬性配置獲取配置值,默認 127 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; } }
由上面源碼可以看出,IntegerCache 會快取值為 -128 ~ 127 的 Integer 對象,那麼什麼時候調用呢? 源碼中只有一個地方:valueOf()
public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
所以當調用 Integer.valueOf 的時候,如果值在 -128 到 127 的範圍,就會使用 IntegerCache 中的快取對象。
解答
針對 new Integer(1) == (new Integer(1)),源碼沒有做特殊處理,就是 new 了兩個不同的對象,他們當然是不相等的,返回 false;
針對 new Integer(1).equals(new Integer(1)),可以看一下 Integer.equals() 函數的實現,函數內部是直接比較兩個對象的 value 是否相等,他們的 value 都是 1,所以返回 true;
針對 Integer.valueOf(1) == Integer.valueOf(1),就是我們前面提到的 IntegerCache 了,Integer.valueOf 會直接使用快取好的對象,兩個值相等,所以對象也是相同的,返回 true;
針對 Integer.valueOf(129) == Integer.valueOf(129),由於快取的範圍是 -128 ~ 127,值 129 顯然是超出範圍了,所以會 new 一個新對象,也不會相等,返回 false;
裝箱拆箱
再看一下以下輸出:
Integer i = 100; Integer j = 100; System.out.print(i == j); //true
以上例子,Java 在編譯是會自動裝箱,編譯為:Integer i = Integer.valueOf(100),又看到了 valueOf,用了快取的 Integer,所以輸出 true。
Integer i = new Integer(100); int j = 100; System.out.print(i == j); //true
以上例子,在 int 和 Integer 相比較時,Java 編譯器會自動把 Integer 拆箱為 int 類型,所以輸出 100。
拓展
好,看完了 Integer,我突然想起了其他的包裝器類會不會也是這樣,於是分別看了一下源碼。
我直接說結果吧,有興趣的同學可以看一下源碼:Long,Short 這兩個類,內部也快取了 -128 ~ 127 的對象,Boolean 內部快取了 TRUE、FALSE 兩個對象。和 Integer 類似,都是在調用 valueOf 方法的時候生效,new 的時候不會這樣。
作 者:ChanghuiN 原文鏈接:https://www.hchstudio.cn/article/2019/223d/ 版權聲明:非特殊聲明均為本站原創作品,轉載時請註明作者和原文鏈接。