java中Integer包裝類裝箱的一個細(xì)節(jié)詳解
前言
java有八個基本數(shù)據(jù)類型,每個都有對應(yīng)的一個包裝類,比如int對應(yīng)的Integer。 Integer 是int的包裝類型,數(shù)據(jù)類型是類,初值為null,從jdk1.5開始,java引入了自動拆裝箱,可以直接進行形如Integer i = 20形式的賦值,編譯器會自動將其轉(zhuǎn)換為Integer i = Integer.valueOf(20)進行裝箱,拆箱則是將int j = i的形式轉(zhuǎn)換成了int j = i.intValue() 。
裝箱有個細(xì)節(jié),如果不注意很容易出錯,來看一下:
Integer i = 20; Integer j = Integer.valueOf(20); System.out.println(i == j);
上面的代碼輸出為
true
好像沒什么問題,那我們形式不變,將數(shù)字20換成200,即
i = 200; j = Integer.valueOf(200); System.out.println(i == j);
同樣的判斷,輸出變成了:
false
這是為什么呢?
先明確一點,經(jīng)過編譯器編譯后,Integer i = 20轉(zhuǎn)換成了Integer i = Integer.valueOf(20) ,和Integer j = Integer.valueOf(20)的定義完全一樣,那為什么將20換成了200后判斷結(jié)果不一樣了呢?
我們來看看Integer.valueOf(int i)方法的內(nèi)部:
public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
可以看出當(dāng)i在某個區(qū)間內(nèi)時,直接返回了緩存數(shù)組IntegerCache.cache中的一個值,超出區(qū)間才new一個新的Integer對象。到這里我們大概就可以得出結(jié)論:20在緩存范圍內(nèi)所以直接用了緩存,但是200超出了緩存區(qū)間所以new了新對象,和原來對象的地址當(dāng)然不會相同,所以返回false
再來看看IntegerCache,這是一個Integer的私有靜態(tài)內(nèi)部類,定義如下:
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low));
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
}
private IntegerCache() {}
}
可以看出默認(rèn)的緩存區(qū)間是-128~127,那么什么情況下會修改這個范圍呢,修改了某個虛擬機參數(shù)的時候,通過代碼也可看出,設(shè)置的這個緩存上限java.lang.Integer.IntegerCache.high值不能小于127,小于的話就會被賦予127,從而失效。
那么這個值怎么設(shè)置呢?我們來看看jdk源碼中怎么解釋IntegerCache這個靜態(tài)內(nèi)部類:
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= 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.
大概意思是:
將-128到127(包含)的數(shù)字做緩存以供自動裝箱使用。緩存在第一次使用時被初始化。大小可以由JVM參數(shù)-xx:autoboxcachemax=option來指定。JVM初始化時此值被設(shè)置成java.lang.Integer.IntegerCache.high屬性并作為私有的系統(tǒng)屬性保存在sun.misc.vm.class中。
可以得到結(jié)論:這個緩存的high值是由JVM參數(shù) -XX:AutoBoxCacheMax= option來指定的。
上述jdk源碼來源于jdk1.7,不同版本實現(xiàn)略有不同,但思路一致。
這種共享常用對象的思路有一個名字,叫享元模式,英文名叫Flyweight,即共享的輕量級元素。其他包裝類如Boolean、Byte、Short、Long、Charactor都有類似的實現(xiàn)。
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關(guān)文章
java中關(guān)于getProperties方法的使用
這篇文章主要介紹了java中關(guān)于getProperties方法的使用,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12
詳解SpringBoot?Start組件開發(fā)之記錄接口日志信息
這篇文章主要為大家介紹了SpringBoot-Start組件開發(fā)之記錄接口日志信息詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-04-04
淺析Java中String與StringBuffer拼接的區(qū)別
String拼接會創(chuàng)建一個新的String對象,存儲拼接后的字符串,StringBuffer拼接是直接在本身拼接,會即時刷新。下面通過本文給大家介紹Java中String與StringBuffer拼接的區(qū)別,感興趣的朋友一起看看吧2017-06-06
Java Web使用簡單的批處理操作(記事本+Tomcat)
這篇文章主要介紹了Java Web使用簡單的批處理操作 ,需要的朋友可以參考下2014-10-10
java輸入多個數(shù)據(jù)(不確定),排序,并求最大值的方法
今天小編就為大家分享一篇java輸入多個數(shù)據(jù)(不確定),排序,并求最大值的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-07-07

