天天看點

java整形包裝類自動拆箱範圍_有關Java包裝類的自動裝箱和拆箱--使用注意事項...

事出有因

在最近準備安卓面試的過程中,一位資深的大神問了我關于裝箱和拆箱的一些知識點。無奈小弟平時沒怎麼關注這個方面的知識點,拿來就是用,完全沒有沒有考慮到使用上的性能損耗和一些注意事項問題。是以經曆此面試之後,決定好好複習一下關于這方面的知識點,并總結出這篇文章,供自己日後快速複習,同時也希望本篇文章能給各位看官帶來收益。

例子1

· 知識點

1 自動裝箱 & 自動拆箱

2 比較符“==”和“equal”,在使用上的注意事項

public static void main(String[] args) {

Integer a = 1;

Integer b = 2;

Integer c = 3;

Integer d = 3;

Integer e = 220;

Integer f = 220;

Long g = 3L;

System.out.println(c == d);

System.out.println(e == f);

System.out.println(c == (a + b));

System.out.println(c.equals(a + b));

System.out.println(g == (a + b));

System.out.println(g.equals(a + b));

}

複制代碼

小夥伴們先猜想上面程式輸出的結果,認真的思考一下。

· 解釋

在程式中變量:a,b,c,d,e,f,g都是對基本資料包裝類,在初始化這些變量的時候,實際上java編譯器幫我們使用裝箱來指派。例如:Integer a = 1; 編譯後換算成 Integer a = Integer.valueOf(1); 這個過程就被稱為裝箱啦,需要注意一點的是變量a為Integer對象類型,為實際儲存值的位址引用。

當列印:c == d的時候,此時兩者的對象類型都是Integer,那麼此時比較的是兩者的位址引用。此處的結果傳回為true,那麼我們能間接得出結論:c和d都指向同一個對象,指向的對象值為3

當列印:e == f的時候,同樣的此時兩者的對象類型都是Integer,那麼此時比較的是兩者的位址引用。但是此處傳回的結果為false,那麼我們能間接得出結論:e和f指向不同的對象,但是對象的值都為220。

對比上面兩條結果,我們是否有疑問。為啥第一條列印為true,第二條列印為false。想要搞懂這其中的原因,那麼就需要知道Integer中的Cache的概念,下面貼出其中的源碼:

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) {

try {

int i = parseInt(integerCacheHighPropValue);

i = Math.max(i, 127);

// Maximum array size is Integer.MAX_VALUE

h = Math.min(i, Integer.MAX_VALUE - (-low) -1);

} catch( NumberFormatException nfe) {

// If the property cannot be parsed into an int, ignore it.

}

}

high = h;

cache = new Integer[(high - low) + 1];

int j = low;

for(int k = 0; k < cache.length; k++)

cache[k] = new Integer(j++);

// range [-128, 127] must be interned (JLS7 5.1.7)

assert IntegerCache.high >= 127;

}

private IntegerCache() {}

}

複制代碼

上面的源碼不是特别複雜,各位看官可以先大緻觀摩一下,再來看我的解析,了解起來能夠事半功倍。

源碼解析:IntegerCache是Integer的靜态内部類,用來緩存Integer對象。使用數組的形式來緩存,并且數組的大小為256,緩存值的範圍為:[-128 ,127]。如果值的取值範圍沒有在這個區間中,那麼這個對象将不會儲存

結論:值為3的Integer對象,會儲存在緩存中。值為220,不在儲存的區間範圍内,是以每次都是建立新的Integer類型對象

當列印“c == (a+b)” 的時候,結果為true。為什麼為true?

我來解析一下這個過程:

a+b等同于a.value+b.value , 其中a.value = 1,b.value = 2 ,是以:a+b的結果為基本類型3(這個過程就是拆箱的過程,一般在遇到算數運算符的時候,包裝類型就是自動拆箱)“c == (a+B)” 就等同于 “c == 3”,因為此時的c的類型為Integer,是以需要拆箱比較,最終的比較形式為:c.value == 3

當列印“c.equals(a+b)”的時候,結果也為true

和上面一樣,解析一下過程:a+b的解析和上面一樣。我們重點來看"c.equals(a+b)",Integer.equals()方法需要傳入Object對象,那麼a+b需要裝箱變為Integer對象。程式就變成“c.equals(Integer.value(3))”,是以結果為true

注意事項:包裝類的裝箱和拆箱涉及到性能損耗,因為程式需要多執行幾步。涉及到基本算術運算符,就會涉及到拆箱,變量初始化涉及到裝箱

當列印“g == (a + b)”,因為(a+b)得到結果為基本類型3。變量g的類型為Long,當執行g == 3的時候需要拆箱變成3 == 3 。是以得到的結果為true。

當列印“g.equals(a + b),結果為false。為什麼結果不是true,因為:g的類型為Long,那麼Long.equals()方法比較的對象類型也需要為Long,源碼如下:

public boolean equals(Object obj) {

if (obj instanceof Long) {

return value == ((Long)obj).longValue();

}

return false;

}

複制代碼

因為a+b得到的結果為整型3,是以程式變成g.equals(Integer.valueOf(3)),可以看到兩者對象的類型都不相同,盡管他們的值都為3,但程式結果還是傳回false

注意事項:當使用不同包裝類的equals方法時候,需要注意比較的類型不同結果直接傳回false

java整形包裝類自動拆箱範圍_有關Java包裝類的自動裝箱和拆箱--使用注意事項...

關于找一找教程網

本站文章僅代表作者觀點,不代表本站立場,所有文章非營利性免費分享。

本站提供了軟體程式設計、網站開發技術、伺服器運維、人工智能等等IT技術文章,希望廣大程式員努力學習,讓我們用科技改變世界。

[有關Java包裝類的自動裝箱和拆箱--使用注意事項]http://www.zyiz.net/tech/detail-128900.html