前言
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()
。
裝箱有個細節(jié),如果不注意很容易出錯,來看一下:
1
2
3
4
|
integer i = 20 ; integer j = integer.valueof( 20 ); system.out.println(i == j); |
上面的代碼輸出為
true
好像沒什么問題,那我們形式不變,將數(shù)字20換成200,即
1
2
3
4
|
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)部:
1
2
3
4
5
6
|
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)部類,定義如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
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() {} } |
可以看出默認的緩存區(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í)價值,如果有疑問大家可以留言交流,謝謝大家對服務(wù)器之家的支持。
原文鏈接:https://www.cnblogs.com/JackPn/p/9392145.html