裝箱 VS 拆箱

java中 的Boolean、Short、Integer、Long、Float、Double類被稱為數(shù)值型基本類型的打包類。為什么叫做打包類呢?

因為我們有時候想讓基本類型像對象一樣操作(對象可以提供更多的信息),就需要使用它們來打包(wrap)java基本類型。這些類的主要目的就是提供對象實例作為殼,將基本類型打包在對象之中,這樣就可以操作這個對象,就像是將基本類型當做對象操作。

?????? Java中這些包裝類有8種,基礎數(shù)據(jù)類型與它們對應的包裝類見下圖

基本類型的包裝類的使用方法為使用new創(chuàng)建包裝類,再傳入相應的基本類型的數(shù)據(jù),如

????????????????????????Integerintwrap = new Inter(data)

Java中基礎數(shù)據(jù)類型與它們的包裝類進行運算時,編譯器會自動幫我們進行轉換,轉換過程對程序員是透明的,這就是裝箱和拆箱。裝箱就是自動將基本數(shù)據(jù)類型轉換為包裝器類型;拆箱就是自動將包裝器類型轉換為基本數(shù)據(jù)類型。

當基礎類型與它們的包裝類有如下幾種情況時,編譯器會自動幫我們進行裝箱或拆箱。

Java中基礎數(shù)據(jù)類型與它們的包裝類進行運算時,編譯器會自動幫我們進行轉換,轉換過程對程序員是透明的,這就是裝箱和拆箱。裝箱就是自動將基本數(shù)據(jù)類型轉換為包裝器類型;拆箱就是自動將包裝器類型轉換為基本數(shù)據(jù)類型。

當基礎類型與它們的包裝類有如下幾種情況時,編譯器會自動幫我們進行裝箱或拆箱。

? 進行 “=”賦值操作,會進行裝箱或拆箱操作,具體因左側類型聲明而異,如,

? ? ? ? Integer num1=99;

Integer num2=1;

? ? ? ? int total=num2;

執(zhí)行上面那句代碼的時候,系統(tǒng)為我們執(zhí)行了:

Integer total = Integer.valueOf(99);

而valueOf源碼為

public static Integer valueOf(int i) {

return? i >= 128 || i < -128 ? new Integer(i) : SMALL_VALUES[i + 128];

}

其中,

private static final Integer[] SMALL_VALUES = new Integer[256];

它是一個靜態(tài)的Integer數(shù)組對象,也就是說最終valueOf返回的都是一個Integer對象。對于Integer,在(-128,128]之間只有固定的256個值,所以為了避免多次創(chuàng)建對象,事先就創(chuàng)建好一個大小為256的Integer數(shù)組SMALL_VALUES,所以如果值在這個范圍內,就可以直接返回我們事先創(chuàng)建好的對象就可以了,它被稱為常量池。

實際上,Short、Byte、Character、Long這幾個類的valueOf方法的實現(xiàn)是類似的。

而Double、Float的valueOf方法的實現(xiàn)是類似的。但它們每次都返回不同的對象。

public static Double valueOf(double d) {

? ? return new Double(d);

}

這里可以用instanceof是關鍵字判斷一個對象是否是另一個對象的實例,如

System.out.println(num1 instanceof Integer);? ? ? ? ? //true

可見,裝箱的過程會創(chuàng)建對應的對象,這個會消耗內存,所以裝箱的過程會增加內存的消耗,影響性能。

執(zhí)行下面那句代碼的時候,系統(tǒng)為我們執(zhí)行了:

int total = num1.intValue();

其中,intValue源碼為

@Override

public int intValue() {

? ? return value;

}

? 進行+,-,*,/混合運算,會進行拆箱操作,如

System.out.println(num1+num2);? ? //100

System.out.println(num1+num2 instanceof? Integer); // error: unexpected type

? 進行>,<比較運算,會執(zhí)行拆箱操作

System.out.println(num1>total);? //true

? 調用equals進行比較,會執(zhí)行拆箱操作,使用“==”比較,會進行封箱操作

大多數(shù)程序設計語言中,使用“==”運算符來判斷兩個變量是否相等。在java中,使用“==”需要注意運算符兩邊的類型。

當==用于基本類型時,是比較兩個變量存儲的值是否相等。但在比較兩個對象的時候,則是在比較兩個引用變量是否引用的是同一個對象。因為“=”的意思是將某個變量名綁定到某個對象,而==是比較兩個變量名是否綁定到同一對象。

如對于如下兩行代碼

? ??????Integer num1=300;

???????Integer num2=300;

300在轉為Integer對象時會new一個對象出來。因為它們不在常量池中,所以是兩個不同的對象

???????System.out.println(num1==num2);????//false

而equals則是判斷兩個對象的值是否相等。

? ??????System.out.println(num1.equals(num2));????? //true

如果改寫代碼為

???????Integer num1=100;

???????Integer num2=100;

?????? 因為100經(jīng)包裝后,放入常量池中,所以有

??????? System.out.println(num1==num2);???? //true

?????? 如果在java中創(chuàng)建對象顯式使用關鍵字new創(chuàng)建對象,如

Integer a = new Inter(100)

Integer b = new Inter(100)

?????? 我們看到該關鍵字,就知道建立了一個新對象,這時它們是兩個不同的對象,因為它們不會存放在常量池中,

??? ?System.out.println(num1==num2);// false

?? ? ArrayList,HashMap等集合類 添加基礎類型數(shù)據(jù)時,執(zhí)行裝箱操作

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容