漲點知識:Java基本數據類型的包裝類Integer的緩存了解吧?

漲點知識:Java基本數據類型的包裝類Integer的緩存瞭解吧?

一、Java中對象的比較

我們都知道,Java的對象名其實是一個引用,指向堆中的某個位置,如果兩個對象指向同一個位置,那麼用==號比較兩個對象,得到的結果就是true。而如果兩個對象指向內存中不同位置,那麼用==號比較的話,會得到false,這個時候要去重寫對象的equals方法來進行比較。

二、Integer中的==比較

漲點知識:Java基本數據類型的包裝類Integer的緩存瞭解吧?

如上圖所示,寫了一段代碼,來比較a和b,c和d。大家猜一下答案應該是什麼呢?

漲點知識:Java基本數據類型的包裝類Integer的緩存瞭解吧?

是不是很奇怪?

通過上述代碼,我們可以得出,a和b其實指向的是同一個對象,而c和d則指向的是不同的對象

讓我們去看看這個類的字節碼。在IDEA左側導航欄中單擊這個類:

漲點知識:Java基本數據類型的包裝類Integer的緩存瞭解吧?

然後點擊view,找到show bytecode,可以查看字節碼:

漲點知識:Java基本數據類型的包裝類Integer的緩存瞭解吧?

看不懂沒關係,我們注意到,當執行Integer a = 100,這條語句的時候,調用的是Integer.valueOf方法。那麼我們去追蹤一下這個方法。

按住ctrl(mac上是command),左鍵單擊Integer,即可進入Integer類。

漲點知識:Java基本數據類型的包裝類Integer的緩存瞭解吧?

我們搜索一下這個類的valueOf方法,代碼如下:

可以看到,當輸入處於IntegerCache.low 和 IntegerCache.high之間的時候,返回的是IntegerCache中的cache數組的值。而大於那個範圍,才是另外去new一個Integer。

讓我們繼續追蹤,什麼是IntegerCache?

它是Integer中的一個靜態內部類,裡邊有一個Integer數組,用來存儲-128到127的值。

漲點知識:Java基本數據類型的包裝類Integer的緩存瞭解吧?

所以答案解開了,因為a和b都是指向IntegerCache中的值為100的那個Integer對象,所以進行==比較的結果返回true。而c和d大於127,所以每次都會重新new一個Integer對象,所以c和d指向的不是內存中的同一個地方,因此==比較的時候會返回false。

三、為什麼引入IntegerCache

IntegerCache是JDK1.5中被引入的,因為這些小數字在生活中被頻繁使用,如果每次使用都去重新new的話,會帶來性能開銷。在第一次使用Integer的時候,IntegerCache中的cache數組就被初始化好。每次用等號給Integer賦值的時候,都會檢查是否在-128和127之間。

注意:只有用=給Integer賦值,才會自動裝箱,隱式去調用valueOf。如果直接new的話,IntegerCache並不起作用:

漲點知識:Java基本數據類型的包裝類Integer的緩存瞭解吧?

上邊的代碼輸出為false。

四、其他包裝類

Byte,Short,Long,Character都有類似於Integer的緩存,其中除了Character是0~127之外,其他的都是-128~127。大家感興趣的可以去看看源碼。另外Integer的Cache範圍可以通過JVM啟動參數來設置,而其他的不行。

漲點知識:Java基本數據類型的包裝類Integer的緩存瞭解吧?


一般來說,如果沒有什麼特別用途,這類問題,可能永遠都不會關注,但有面試官喜歡問,以檢驗你的基本功咋樣。所以,就多積累吧,漲點見識也不錯嘛~


看完了,記得關注、分享、點個贊啥的^_^


分享到:


相關文章: