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í)行裝箱操作