基本類型和包裝類型的自動(dòng)裝箱拆箱原理并不復(fù)雜,但是在日常使用中頻率極高,如果不理解語(yǔ)法糖背后的奧秘,很可能陷入誤區(qū)而不自知,下面以一個(gè)例子說(shuō)明這個(gè)語(yǔ)法糖的工作原理
這個(gè)例子摘自深入理解java虛擬機(jī)第二版(強(qiáng)烈推薦閱讀)
public static void main(String[] args) {
//part1
Integer a = 1;
Integer b = 2;
Integer c = 3;
Integer d = 3;
Integer e = 321;
Integer f = 321;
Long g = 3L;
//part2
System.out.println(c == d);//1
System.out.println(e == f);//2
System.out.println(c == (a + b));//3
System.out.println(c.equals(a + b));//4
System.out.println(g == (a + b));//5
System.out.println(g.equals(a + b));//6
}
猜測(cè)結(jié)果前需要說(shuō)明以下幾個(gè)基本原則
- 包裝類的==運(yùn)算在不遇到算數(shù)運(yùn)算的情況下不會(huì)自動(dòng)拆箱
- 包裝類型存在緩存,如Integer在-128~127是有緩存的,具體參見(jiàn)8大基本類型的包裝類型緩存探究
- 包裝類型的equals不處理轉(zhuǎn)型問(wèn)題
- 包裝類型遇到算數(shù)運(yùn)算時(shí)會(huì)進(jìn)行自動(dòng)拆箱
- 基本類型在需要包裝類型時(shí)會(huì)進(jìn)行自動(dòng)裝箱
結(jié)果如下
true//1
false//2
true//3
true//4
true//5
false//6
下面結(jié)合反編譯出的代碼分析
public static void main(String[] args) {
//part1
Integer a = Integer.valueOf(1);
Integer b = Integer.valueOf(2);
Integer c = Integer.valueOf(3);
Integer d = Integer.valueOf(3);
Integer e = Integer.valueOf(321);
Integer f = Integer.valueOf(321);
Long g = Long.valueOf(3L);
//part2
System.out.println(c == d);//1
System.out.println(e == f);//2
System.out.println(c.intValue() == a.intValue() + b.intValue());//3
System.out.println(c.equals(Integer.valueOf(a.intValue() + b.intValue())));//4
System.out.println(g.longValue() == a.intValue() + b.intValue());//5
System.out.println(g.equals(Integer.valueOf(a.intValue() + b.intValue())));//6
}
觀察原代碼和反編譯后代碼可以看出
- part1 定義a~f時(shí)發(fā)生了自動(dòng)裝箱,并且使用了緩存(Integer.valueOf())
- part2 在進(jìn)行==比較時(shí)發(fā)生了自動(dòng)拆箱(Integer.intValue())
對(duì)于語(yǔ)句進(jìn)行分析
- c==d 對(duì)于對(duì)象==比較的是他們的內(nèi)存地址,由于c,d都是從Integer的緩存中獲取的,是同一個(gè)對(duì)象,因此結(jié)果是true
- e==f 與上面相同,但是321已經(jīng)不在緩存范圍內(nèi),因此結(jié)果是false
- c=a+b 發(fā)生自動(dòng)拆箱,進(jìn)行基本類型的==比較,3=1+2,結(jié)果為true
- c.equals(a+b) 首先由規(guī)則4,a+b進(jìn)行自動(dòng)拆箱,然后由于規(guī)則5,equals需要包裝類型,進(jìn)行自動(dòng)裝箱且?guī)в芯彺?得到對(duì)象Integer(3),它和c都是從緩存時(shí)獲取的,因此結(jié)果true
- g==a+b a+b發(fā)生自動(dòng)拆箱,而后類型提升為long,因此結(jié)果為true
- g.equals(a+b) 由規(guī)則3,最終比較時(shí)為L(zhǎng)ong.equals(Integer),類型都不同,結(jié)果當(dāng)然為false