Java拆裝箱深度剖析
先來看一段代碼:
public class Main{
public static void main(String[] args){
Integer num1 = 100;
Integer num2 = 100;
Integer num3 = 200;
Integer num4 = 200;
'''//輸出結(jié)果'''
System.out.println(num1==num2);
System.out.println(num3==num4);
}
}
猜猜結(jié)果是什么?
很多人都會認(rèn)為結(jié)果全為true,但結(jié)果去不是這樣的
true
false
為什么是這樣的結(jié)果?如果用內(nèi)存來解釋結(jié)果的話,num1和num2指向的是同一個對象,而num3和num4則指向的確是不同的對象。接下來就告訴你為什么,看一看Integer類型的valueof方法的源碼:
public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + 128];
return new Integer(i);
}
其中IntegerCache的實現(xiàn):
'''// IntegerCache,一個內(nèi)部類,注意它的屬性都是定義為static final'''
private static class IntegerCache {
static final int high; '''//緩存上界,暫為null'''
static final Integer cache[]; '''//緩存的整型數(shù)組'''
'''// 塊,為什么定義為塊'''
static {
final int low = -128; '''// 緩存下界,不可變了。只有上界可以改變'''
'''// high value may be configured by property'''
'''// h值,可以通過設(shè)置jdk的AutoBoxCacheMax參數(shù)調(diào)整(以下有解釋),自動緩存區(qū)間設(shè)置為[-128,N]。注意區(qū)間的下界是固定'''
int h = 127;
if (integerCacheHighPropValue != null) {
'''// Use Long.decode here to avoid invoking methods that'''
'''// require Integer's autoboxing cache to be initialized'''
// 通過解碼integerCacheHighPropValue,而得到一個候選的上界值'''
int i = Long.decode(integerCacheHighPropValue).intValue();
'''// 取較大的作為上界,但又不能大于Integer的邊界MAX_VALUE'''
i = Math.max(i, 127);
'''// Maximum array size is Integer.MAX_VALUE'''
h = Math.min(i, Integer.MAX_VALUE - -low);
}
high = h; '''//上界確定'''
'''// 就可以創(chuàng)建緩存塊,注意緩存數(shù)組大小'''
cache = new Integer[(high - low) + 1]; //
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++); '''// -128到high值逐一分配到緩存數(shù)組'''
}
private IntegerCache() {}
}
通過這兩段代碼可以看出,在通過valueof方法創(chuàng)建Integer類型對象時,取值范圍為[-128,127],數(shù)值在這個區(qū)間里,指針指向IntegerCache.cache中已經(jīng)存在的對象引用,當(dāng)數(shù)值超出這個范圍,就會創(chuàng)建一個新的對象。
有一點需要注意的是,并不是所有的類型都是這個范圍,看Double類型:
public class Main{
public static void main(String[] args){
Double i1 = 100.0;
Double i2 = 100.0;
Double i3 = 200.0;
Double i4 = 200.0;
System.out.println(i1==i2);
System.out.println(i3==i4);
}
}
最終的輸出結(jié)果:
false
false
具體為什么回事這樣的結(jié)果,大伙可以去看看源代碼中Double valueof方法的實現(xiàn),其和Integer valueof方法不同,是因為在某個范圍內(nèi)的整型數(shù)值的個數(shù)是有限的,而浮點數(shù)卻不是。
注意,Integer、Short、Byte、Character、Long這幾個類的valueOf方法的實現(xiàn)是類似的。
Double、Float的valueOf方法的實現(xiàn)是類似的。
拉下了一個,Boolean類型的結(jié)果有兩個True or False。直接看源代碼:
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}
而其中的TRUE和FALSE是這樣定義的:
public static final Boolean TRUE = new Boolean(true); '''/** ''' '''* The <code>Boolean</code> object corresponding to the primitive ''' '''* value <code>false</code>. ''' '''*/''' public static final Boolean FALSE = new Boolean(false);
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
JDK17在Windows安裝及環(huán)境變量配置超詳細(xì)的教程
這篇文章主要介紹了JDK17在Windows安裝及環(huán)境變量配置超詳細(xì)的教程,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-11-11
springboot結(jié)合mybatis操作事務(wù)配置的處理
在操作數(shù)據(jù)庫的時候,經(jīng)常會使用事務(wù)的處理,本文主要介紹了springboot結(jié)合mybatis操作事務(wù)配置的處理,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-07-07
Java 中的vector和list的區(qū)別和使用實例詳解
在大家還沒有了解vector,list,deque的知識之前,我先給大家介紹下stl,本文重點給大家介紹vector和list的區(qū)別及使用,感興趣的的朋友一起看看吧2017-09-09
spring boot 自定義參數(shù)過濾器,把傳入的空字符轉(zhuǎn)換成null方式
這篇文章主要介紹了spring boot 自定義參數(shù)過濾器,把傳入的空字符轉(zhuǎn)換成null方式。具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08
java使用zookeeper實現(xiàn)的分布式鎖示例
這篇文章主要介紹了java使用zookeeper實現(xiàn)的分布式鎖示例,需要的朋友可以參考下2014-05-05

