由自动装箱和拆箱引发我看Integer源码
背景和問題
在看別人整理的資料時,看到如下一段代碼:
package?com.sitech.test;/**
?*?自動裝箱和拆箱?jdk1.6
?*?@author?liaowp
?*?*/public?class?TestInteger?{????public?static?void?main(String[]?args)?{
????????Integer?i1?=?80,?i2?=?80,?i3?=?999,?i4?=?999;
????????System.out.println(i1?==?i2);//true
????????System.out.println(i3?==?i4);//false????}
}
如果沒有看過源碼的同學肯定覺的答案要么是2個true要么是2個false。我剛看到這一段代碼的時候也覺的是2個true,感覺自己100%確定,不過真正運行之后才發現傻眼了,一個true一個false,這是Bug吧。其實LZ以前看過一部分Integer源碼了,但是現在想想好像看的不認真,尷尬了。于是被這個問題觸發了LZ要認真看一次Integer源碼了(我要認真了,哈哈)。
我們還是回到上面那個問題吧,先把問題解決了在吹nb。我們可以看到上面的代碼4個變量都是Integer的引用,所以輸出的==運算比較的不是Integer值而是Integer引用。裝箱的本質是什么呢?當我們給一個Integer對象賦一個int值的時候,會調用Integer類的靜態方法valueOf,我們看一看valueOf方法就知道為什么會有這樣的結果了。
????/**
?????*?Returns?an?{@code?Integer}?instance?representing?the?specified
?????*?{@code?int}?value.??If?a?new?{@code?Integer}?instance?is?not
?????*?required,?this?method?should?generally?be?used?in?preference?to
?????*?the?constructor?{@link?#Integer(int)},?as?this?method?is?likely
?????*?to?yield?significantly?better?space?and?time?performance?by
?????*?caching?frequently?requested?values.
?????*
?????*?This?method?will?always?cache?values?in?the?range?-128?to?127,
?????*?inclusive,?and?may?cache?other?values?outside?of?this?range.
?????*
?????*?@param??i?an?{@code?int}?value.
?????*?@return?an?{@code?Integer}?instance?representing?{@code?i}.
?????*?@since??1.5?????*/
????public?static?Integer?valueOf(int?i)?{//是一個靜態方法?IntegerCache是一個內部類????????assert?IntegerCache.high?>=?127;//斷言??參考http://lavasoft.blog.51cto.com/62575/43735/????????if?(i?>=?IntegerCache.low?&&?i?<=?IntegerCache.high)//如果i大于對于IntegerCache.low()且i小于等于IntegerCache.high????????????return?IntegerCache.cache[i?+?(-IntegerCache.low)];//直接從緩存取出來????????return?new?Integer(i);//新創建一個Integer對象
????}
從上面的代碼中我們可以看出Integer維持了一個緩存系統,如果在緩存的范圍內直接取出來就好了,雅思培訓機構如果不在的就要創建新的Integer對象。但是具體緩存范圍是什么的,我們在深入進去看看:
????/**
?????*?Cache?to?support?the?object?identity?semantics?of?autoboxing?for?values?between
?????*?-128?and?127?(inclusive)?as?required?by?JLS.
?????*
?????*?The?cache?is?initialized?on?first?usage.??The?size?of?the?cache
?????*?may?be?controlled?by?the?-XX:AutoBoxCacheMax=<size>?option.
?????*?During?VM?initialization,?java.lang.Integer.IntegerCache.high?property
?????*?may?be?set?and?saved?in?the?private?system?properties?in?the
?????*?sun.misc.VM?class.?????*/
????private?static?class?IntegerCache?{//靜態類哦????????static?final?int?low?=?-128;//最小值是-128????????static?final?int?high;//最高????????static?final?Integer?cache[];//緩存數組??這三個都final,不可修改的????????static?{//靜態代碼塊???靜態代碼塊會比改造方法先執行????????????//?high?value?may?be?configured?by?property
????????????int?h?=?127;//默認的
????????????String?integerCacheHighPropValue?=//定義一個String?
????????????????sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");//取得設置的值????????????if?(integerCacheHighPropValue?!=?null)?{//如果設置了就用設置的值????????????????int?i?=?parseInt(integerCacheHighPropValue);//把String轉換為int
????????????????i?=?Math.max(i,?127);//獲得i和127的更大的一個,其實是不能小與默認的????????????????//?Maximum?array?size?is?Integer.MAX_VALUE
????????????????h?=?Math.min(i,?Integer.MAX_VALUE?-?(-low));//如果取的小的那個,不能超過Integer的最大值+low
????????????}
????????????high?=?h;//最大值為127
????????????cache?=?new?Integer[(high?-?low)?+?1];//創建緩存數組大小????????????int?j?=?low;//最小值????????????for(int?k?=?0;?k?<?cache.length;?k++)
????????????????cache[k]?=?new?Integer(j++);//緩存初始化
????????}????????private?IntegerCache()?{}//私有構造
????}
問題解決
Integer的緩存
看完之后我相信基本都知道為啥一開始的那一段代碼會這樣了,我現在做一個小的總結,Integer里面有一個內部類IntegerCache,是用來做緩存優化性能的。默認緩存了-128到127中間的數字,據說這些使的比較頻繁。其實java里面好多的類都有這樣的優化。如果在-128-127之間的就直接拿緩存的,不在的就new一個Integer。所以這也就解釋了上面的那個問題了嘛
轉載于:https://blog.51cto.com/zhangtaoze/1917470
總結
以上是生活随笔為你收集整理的由自动装箱和拆箱引发我看Integer源码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Server 2012 RDS ‘the
- 下一篇: 启用第三方Chrome插件