一、簡介
Java為每種基本數(shù)據(jù)類型都提供了對應(yīng)的包裝類型,裝箱就是自動將基本數(shù)據(jù)類型轉(zhuǎn)換為包裝類型;拆箱就是自動將包裝類型轉(zhuǎn)換為基本數(shù)據(jù)類型。
一般可以通過javap -c 命令可以反編譯class文件獲取拆箱和裝箱是如何實(shí)現(xiàn)的。就比如Integer,在裝箱的時候自動調(diào)用的Integer的valueOf(int)方法.而在拆箱的時候自動調(diào)用Integer的intValue方法,其他的類型也類似.
因此可以用一句話總結(jié)裝箱和拆箱的實(shí)現(xiàn)過程:
?裝箱過程是通過調(diào)用包裝器的valueOf方法實(shí)現(xiàn)的,而拆箱過程是通過調(diào)用包裝器的 xxxValue方法實(shí)現(xiàn)的。(xxx代表對應(yīng)的基本數(shù)據(jù)類型)。
二、相關(guān)問題
(1)在裝箱過程中,即通過valueOf方法創(chuàng)建Integer對象的時候,如果數(shù)值在[-128,127]之間,會返回常量池中事先已經(jīng)創(chuàng)建好的對象;否則創(chuàng)建一個新的Integer對象。
Integer i1 = 100;
Integer i2 = 100;
Integer i3 = 200;
Integer i4 = 200;
System.out.println(i1==i2);//true
System.out.println(i3==i4);//false
而Double類的valueOf方法采用了與Integer類的valueOf方法不同的實(shí)現(xiàn)。因?yàn)樵谀硞€范圍內(nèi)的整型數(shù)值的個數(shù)是有限的,而浮點(diǎn)數(shù)卻不是。注意,Integer、Short、Byte、Character、Long這幾個類的valueOf方法的實(shí)現(xiàn)是類似的。Double、Float的valueOf方法的實(shí)現(xiàn)是類似的。
Double i1 = 100.0;
Double i2 = 100.0;
Double i3 = 200.0;
Double i4 = 200.0;
System.out.println(i1==i2);//false
System.out.println(i3==i4);//false
Boolean類的valueOf直接返回事先創(chuàng)建好的對象。
Boolean i1 = false;
Boolean i2 = false;
Boolean i3 = true;
Boolean i4 = true;
System.out.println(i1==i2);//true
System.out.println(i3==i4);//true
(2)談?wù)処nteger i = new Integer(xxx)和Integer i =xxx;這兩種方式的區(qū)別?
答:第一種方式不會觸發(fā)自動裝箱的過程;而第二種方式會觸發(fā);另外,如果數(shù)值在[-128,127]之間,第二種方式是不會創(chuàng)建新對象的。
(3)相關(guān)問題:
?需要注意的是:當(dāng) "=="運(yùn)算符的兩個操作數(shù)都是包裝器類型的引用,則是比較指向的是否是同一個對象。
?而如果其中有一個操作數(shù)是表達(dá)式(即包含算術(shù)運(yùn)算)則比較的是數(shù)值(即會觸發(fā)自動拆箱的過程)。
?另外,對于包裝器類型,equals方法并不會進(jìn)行類型轉(zhuǎn)換(即數(shù)值相同的Long型和Integer型,通過equals比較,必定返回false)。
Integer a = 1;
Integer b = 2;
Integer c = 3;
Integer d = 3;
Integer e = 321;
Integer f = 321;
Long g = 3L;
Long h = 2L;
System.out.println(c==d); //true
System.out.println(e==f); //false
System.out.println(c==(a+b)); //true,a+b先拆箱,再==運(yùn)算,同樣是拆箱
System.out.println(c.equals(a+b));//true,a+b先拆箱,再將int類型的結(jié)果裝箱
System.out.println(g==(a+b)); //true,a+b先拆箱,再==運(yùn)算,同樣是拆箱
System.out.println(g.equals(a+b));//false,a+b先拆箱,再將int類型的結(jié)果裝箱,類型不同,直接返回false
System.out.println(g.equals(a+h));//false,a+b先拆箱,運(yùn)算之后,觸發(fā)類型晉升,結(jié)果為long類型,再裝箱,類型相同,值相同,返回true