特性列表
-
自動化拆箱與裝箱
-
枚舉
-
泛型
-
增強for循環(huán)
-
可變參數(shù)
-
注解
-
靜態(tài)導入
-
線程池
-
Generics 類
-
元數(shù)據(jù)
-
協(xié)變返回類型
拆箱與裝箱
? java語言從設計之初就標識其為面向對象的一門語言,并提供了4類八種基本數(shù)據(jù)類型趴樱,在設計時每種基本類型均對應了相應的包裝類型:
int | Integer |
---|---|
byte | Byte |
short | Short |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
什么是拆箱,什么又是裝箱?
? 拆箱與裝箱招驴,這兩個名稱很容易讓人聯(lián)想到工廠車間中流水線上包裝產(chǎn)品和打開產(chǎn)品時的兩個常見操作坠非,舉個栗子:我們每個開發(fā)人員用到的筆記本電腦,背后需要有對應的生產(chǎn)廠家來負責生產(chǎn)組裝肺樟,當電腦生產(chǎn)組裝完畢不是直接拿到了市場上就行銷售,此時會給該電腦打上標簽,型號并進行打包便于后續(xù)運輸和銷售乘综,而對于購買用戶來說,我們在網(wǎng)上下過單后拿到的也不是一個裸機套硼,我們拿到的是被廠商包裝過得一臺電腦產(chǎn)品卡辰,此時,激動的你會小手顫抖的小心打開電腦包裝盒,里面有廠商給你打包好的電腦九妈,電源反砌,說明書等,說到這里,相信大家對于裝箱與拆箱過程有整體了解。
? 為什么需要自動裝箱與拆箱?
Java早年設計的一個缺陷式廷,基本數(shù)據(jù)類型不是對象啤它,自然不是Object的子類,
需要裝箱才能把數(shù)據(jù)類型變成一個類,那就可以把裝箱過后的基本數(shù)據(jù)類型當做一個對象,就可以調用object子類的接口。而且基本數(shù)據(jù)類型是不可以作為形參使用的同衣,裝箱后就可以滿足使用了。
? Jdk1.5 引入了基本類型自動化的裝箱與拆箱新特性壶运,這兩個操作不需要開發(fā)人員在負責代碼的處理耐齐,而是交給編譯器來自動化實現(xiàn),想想是不是很美蒋情?
? Jdk 對于裝箱與拆箱的定義描述:
? 裝箱:程序在運行時自動將基本數(shù)據(jù)類型轉換為包裝類型埠况;
? 拆箱:程序在運行時自動將包裝類型轉換為基本數(shù)據(jù)類型。
代碼演示
Java5之前拆箱與裝箱示例代碼((這里以Integer類型為例棵癣,其他類型同樣適用辕翰,讀者自行驗證)):
/**
* Java5之前拆箱與裝箱代碼示例
*/
public static void test_boxing_unboxing_4(){
/**
* Java5 之前得到一個2048的包裝對象
* 需要通過手動方式借助帶參構造器 構造2048 Integer 對象
*/
Integer i=new Integer(2048);
System.out.println(i);
/**
* Java5 之前由包裝類型得到一個2048的基本類型
* 通過調用Integer包裝對象intValue方法獲取整數(shù)2048
*/
int h=i.intValue();
System.out.println(h);
}
Java5之后拆箱與裝箱示例代碼:
public static void main(String[] args) {
/**
* 自動化裝箱:程序在運行時自動將基本數(shù)據(jù)類型轉換為包裝類型;
* Java5開始提供了自動裝箱功能
* 比如我要定義一個2048的整型對象 從Java5 開始就可以這樣來編寫你的代碼
* 這個過程程序在運行中會自動根據(jù)我們提供的2048數(shù)字創(chuàng)建一個Integer對象
*/
Integer i=2048;// 裝箱
System.out.println(i);
/**
*自動化拆箱:程序在運行時自動將包裝類型轉換為基本數(shù)據(jù)類型狈谊。
* Java5開始提供了自動裝箱功能
* 比如我要定義一個1024的整型對象l 此時程序在運行時就會產(chǎn)生裝箱操作
* 后續(xù)定義變量x 值為l 此時Integer 類型的l變量會將自已引用的1024數(shù)值賦給x 這個過程就是拆箱
*/
Integer l=1024;// 裝箱
int x=l;// 拆箱
System.out.println(x);
}
? 從以上代碼可以看出 Java5 之后對于基本數(shù)據(jù)類型的裝箱與拆箱的代碼變得相當簡潔喜命,大大簡化了我們平時開發(fā)代碼量。
裝箱與拆箱實現(xiàn)
在項目編譯目錄下執(zhí)行 通過反編譯命令 javap -c河劝,編譯對應class 文件 如下圖:
可以看得到:Java5 之后實現(xiàn)自動化裝箱 內部實際上執(zhí)行的是valueof 方法 壁榕,而自動化拆箱內部執(zhí)行的為intValue方法。
自動裝箱與拆箱面試常見“坑”
-
Integer 比較問題
public static void test_autoboxing_unboxing(){
Integer b1 = 66;
Integer b2 = 66;
Integer b3 = 201;
Integer b4 = 201;
System.out.println(b1 == b2);// true or false?
System.out.println(b3 == b4);// true or false?
}
這里第一個輸出為true,而第二個輸出為false赎瞎。
答案可以從源碼分析得到:當數(shù)字在-127 ~128 之間時返回指向IntegerCache.cache中已經(jīng)存在的對象的引用牌里;否則創(chuàng)建一個新的Integer對象。
-
Double 比較問題
public static void test_autoboxing_unboxing02(){
Double b1 = 66.0;
Double b2 = 66.0;
Double b3 = 201.0;
Double b4 = 201.0;
System.out.println(b1==b2);
System.out.println(b3==b4);
}
這里兩次輸出均為false务甥。
答案可以從源碼分析得到每次得到的double 對象均是一個新創(chuàng)建后的對象牡辽,變量的地址是不一樣的,那為什么Double類的valueOf方法會采用與Integer類的valueOf方法不同的實現(xiàn)?很簡單:在某個范圍內的整型數(shù)值的個數(shù)是有限的敞临,而浮點數(shù)卻不是
注意,Integer催享、Short、Byte哟绊、Character、Long這幾個類的valueOf方法的實現(xiàn)是類似的。Double票髓、Float的valueOf方法的實現(xiàn)是類似的攀涵。