Java自動(dòng)裝箱與拆箱及其陷阱分析_第1頁(yè)
Java自動(dòng)裝箱與拆箱及其陷阱分析_第2頁(yè)
Java自動(dòng)裝箱與拆箱及其陷阱分析_第3頁(yè)
Java自動(dòng)裝箱與拆箱及其陷阱分析_第4頁(yè)
Java自動(dòng)裝箱與拆箱及其陷阱分析_第5頁(yè)
已閱讀5頁(yè),還剩4頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

本文格式為Word版,下載可任意編輯——Java自動(dòng)裝箱與拆箱及其陷阱分析Java自動(dòng)裝箱與拆箱及其陷阱分析

Java中一個(gè)分外重要也分外好玩的特性,就是自動(dòng)裝箱與拆箱,本文是我探尋整理的關(guān)于Java自動(dòng)裝箱與拆箱及其陷阱分析,給大家做個(gè)參考,夢(mèng)想對(duì)大家有所扶助!想了解更多相關(guān)信息請(qǐng)持續(xù)關(guān)注我們我!

拆箱Unboxing

定義

Integerinteger100=100;

intint100=integer100;

從上面的代碼中,大家可看出integer100為一個(gè)Integer類型的引用,int100為一個(gè)int類型的原始數(shù)據(jù)類型。但是,我們可以將一個(gè)Integer類型的對(duì)象賦值給其相應(yīng)原始數(shù)據(jù)類型的變量。這便是拆箱。

拆箱與裝箱是相反的操作。裝箱是將一個(gè)原始數(shù)據(jù)類型賦值給相應(yīng)封裝類的變量。而拆箱那么是將一個(gè)封裝類的變量賦值給相應(yīng)原始數(shù)據(jù)類型的變量。裝箱、拆箱的名字也取得相當(dāng)貼切。

原理

筆者相信大家也都猜到了,拆箱過(guò)程中jdk為我們做了什么。我們還是通過(guò)測(cè)驗(yàn)來(lái)證明我們的揣摩吧。

在以上代碼的其次行代碼打上斷點(diǎn),即在"intint100=integer100;'上打上斷點(diǎn),跟蹤一下。

我們可以看到,程序跳轉(zhuǎn)到了Integer的intValue方法。

/**

*ReturnsthevalueofthiscodeInteger/codeasan

*codeint/code.

*/

publicintintValue

returnvalue;

也就是,jdk幫我們完成了對(duì)intValue方法的.調(diào)用。對(duì)于以上的測(cè)驗(yàn)而言,便是調(diào)用integer100的intValue方法,將其返回值賦給了int100。

擴(kuò)展

測(cè)驗(yàn)1

Integerinteger400=400;

intint400=400;

System.out.printlninteger400==int400;

在以上代碼的第三行中,integer400與int400執(zhí)行了==運(yùn)行。而這兩個(gè)是不同類型的變量,畢竟是integer400拆箱了,還是int400裝箱了呢?運(yùn)行結(jié)果是什么呢?

==運(yùn)算是判斷兩個(gè)對(duì)象的地址是否相等或者判斷兩個(gè)根基數(shù)據(jù)類型的值是否相等。所以,大家很輕易揣測(cè)到,假設(shè)integer400拆箱了,那么說(shuō)明比較的是兩個(gè)根基類型的值,那此時(shí)必然相等,運(yùn)行結(jié)果為true;假設(shè)int400裝箱了,那么說(shuō)明比較的是兩個(gè)對(duì)象的地址是否相等,那此時(shí)地址必然不相等,運(yùn)行結(jié)果為false。(至于為什么筆者對(duì)它們賦值為400,就是后面將要講到的陷阱有關(guān))。

我們實(shí)際的運(yùn)行結(jié)果為true。所以是integer400拆箱了。對(duì)代碼跟蹤的結(jié)果也證明這一點(diǎn)。

測(cè)驗(yàn)2

Integerinteger100=100;

intint100=100;

System.out.printlninteger100.equalsint100;

在以上代碼的第三行中,integer100的方法equals的參數(shù)為int100。我們知道equals方法的參數(shù)為Object,而不是根基數(shù)據(jù)類型,因而在這里必然是int100裝箱了。對(duì)代碼跟蹤的結(jié)果也證領(lǐng)略這一點(diǎn)。

其實(shí),假設(shè)一個(gè)方法中參數(shù)類型為原始數(shù)據(jù)類型,所傳入的參數(shù)類型為其封裝類,那么會(huì)自動(dòng)對(duì)其舉行拆箱;相應(yīng)地,假設(shè)一個(gè)方法中參數(shù)類型為封裝類型,所傳入的參數(shù)類型為其原始數(shù)據(jù)類型,那么會(huì)自動(dòng)對(duì)其舉行裝箱。

測(cè)驗(yàn)3

Integerinteger100=100;

intint100=100;

Longlong200=200l;

System.out.printlninteger100+int100;

System.out.printlnlong200==integer100+int100;

System.out.printlnlong200.equalsinteger100+int100;

在第一個(gè)測(cè)驗(yàn)中,我們已經(jīng)得知,當(dāng)一個(gè)根基數(shù)據(jù)類型與封裝類舉行==運(yùn)算時(shí),會(huì)將封裝類舉行拆箱。那假設(shè)+、-、*、/呢?我們?cè)谶@個(gè)測(cè)驗(yàn)中,就可知道。

假設(shè)+運(yùn)算,會(huì)將根基數(shù)據(jù)類型裝箱,那么:

?第4行中,integer100+int100就會(huì)得到一個(gè)類型為Integer且value為200的對(duì)象o,并執(zhí)行這個(gè)對(duì)象的toString方法,并輸出'200';

?第5行中,integer100+int100就會(huì)得到一個(gè)類型為Integer且value為200的對(duì)象o,==運(yùn)算將這個(gè)對(duì)象與long200對(duì)象舉行比較,鮮明,將會(huì)輸出false;

?第6行中,integer100+int100就會(huì)得到一個(gè)類型為Integer且value為200的對(duì)象o,Long的equals方法將long200與o比較,由于兩都是不同類型的封裝類,因而輸出false;

假設(shè)+運(yùn)算,會(huì)將封裝類舉行拆箱,那么:

?第4行中,integer100+int100就會(huì)得到一個(gè)類型為int且value為200的根基數(shù)據(jù)類型b,再將b舉行裝箱得到o,執(zhí)行這個(gè)對(duì)象的toString方法,并輸出'200';

?第5行中,integer100+int100就會(huì)得到一個(gè)類型為int且value為200的根基數(shù)據(jù)類型b1,==運(yùn)算將long200舉行拆箱得到b2,鮮明b1==b2,輸出true;

?第6行中,integer100+int100就會(huì)得到一個(gè)類型為int且value為200的根基數(shù)據(jù)類型b,Long的equals方法將b舉行裝箱,但裝箱所得到的是類型為Integer的對(duì)象o,由于o與long200為不同的類型的對(duì)象,所以輸出false;

程序運(yùn)行的結(jié)果為:

200

true

false

因而,其次種揣測(cè)是正確,即在+運(yùn)算時(shí),會(huì)將封裝類舉行拆箱。

Java自動(dòng)裝箱與拆箱及其陷阱分析

陷阱

陷阱1

Integerinteger100=null;

intint100=integer100;

這兩行代碼是完全合法的,完全能夠通過(guò)編譯的,但是在運(yùn)行時(shí),就會(huì)拋出空指針奇怪。其中,integer100為Integer類型的對(duì)象,它當(dāng)然可以指向null。但在其次行時(shí),就會(huì)對(duì)integer100舉行拆箱,也就是對(duì)一個(gè)null對(duì)象執(zhí)行intValue方法,當(dāng)然會(huì)拋出空指針奇怪。所以,有拆箱操作時(shí)確定要更加留神封裝類對(duì)象是否為null。

陷阱2

Integeri1=100;

Integeri2=100;

Integeri3=300;

Integeri4=300;

System.out.printlni1==i2;

System.out.printlni3==i4;

由于i1、i2、i3、i4都是Integer類型的,所以我們想,運(yùn)行結(jié)果理應(yīng)都是false。但是,真實(shí)的運(yùn)行結(jié)果為"System.out.printlni1==i2;'為true,但是"System.out.printlni3==i4;'為false。也就意味著,i1與i2這兩個(gè)Integer類型的引用指向了同一個(gè)對(duì)象,而i3與i4指向了不同的對(duì)象。為什么呢?不都是調(diào)用Integer.valueOfinti方法嗎?

讓我們?cè)倏纯碔nteger.valueOfinti方法。

/**

*ReturnsattInteger/ttinstancerepresentingthespecified

*ttint/ttvalue.

*IfanewttInteger/ttinstanceisnotrequired,thismethod

*shouldgenerallybeusedinpreferencetotheconstructor

*@link#Integerint,asthismethodislikelytoyield

*significantlybetterspaceandtimeperformancebycaching

*frequentlyrequestedvalues.

*

*@paramiancodeint/codevalue.

*@returnattInteger/ttinstancerepresentingtti/tt.

*@since1.5

*/

publicstaticIntegervalueOfinti

ifi=-128i=IntegerCache.high

returnIntegerCache.cache[i+128];

else

returnnewIntegeri;

我們可以看到當(dāng)i=-128且i=IntegerCache.high時(shí),直接返回IntegerCache.cache[i+128]。其中,IntegerCache為Integer的內(nèi)部靜態(tài)類,其原碼如下:

privatestaticclassIntegerCache

staticfinalinthigh;

staticfinalIntegercache[];

static

finalintlow=-128;

//highvaluemaybeconfiguredbyproperty

inth=127;

ifintegerCacheHighPropValue!=null

//UseLong.decodeheretoavoidinvokingmethodsthat

//requireIntegersautoboxingcachetobeinitialized

inti=Long.decodeintegerCacheHighPropVValue;

i=Math.maxi,127;

//MaximumarraysizeisInteger.MAX_VALUE

h=Math.mini,Integer.MAX_VALUE--low;

high=h;

cache=newInteger[high-low+1];

intj=low;

forintk=0;kcache.length;k++

cache[k]=newIntegerj++;

privateIntegerCache

我們可以領(lǐng)會(huì)地看到,IntegerCache有靜態(tài)成員變量cache,為一個(gè)擁有256個(gè)元素的數(shù)組。在IntegerCach

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論