java自動(dòng)裝箱拆箱語(yǔ)法糖是如何工作的?

基本類型和包裝類型的自動(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è)基本原則

  1. 包裝類的==運(yùn)算在不遇到算數(shù)運(yùn)算的情況下不會(huì)自動(dòng)拆箱
  2. 包裝類型存在緩存,如Integer在-128~127是有緩存的,具體參見(jiàn)8大基本類型的包裝類型緩存探究
  3. 包裝類型的equals不處理轉(zhuǎn)型問(wèn)題
  4. 包裝類型遇到算數(shù)運(yùn)算時(shí)會(huì)進(jìn)行自動(dòng)拆箱
  5. 基本類型在需要包裝類型時(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)行分析

  1. c==d 對(duì)于對(duì)象==比較的是他們的內(nèi)存地址,由于c,d都是從Integer的緩存中獲取的,是同一個(gè)對(duì)象,因此結(jié)果是true
  2. e==f 與上面相同,但是321已經(jīng)不在緩存范圍內(nèi),因此結(jié)果是false
  3. c=a+b 發(fā)生自動(dòng)拆箱,進(jìn)行基本類型的==比較,3=1+2,結(jié)果為true
  4. 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
  5. g==a+b a+b發(fā)生自動(dòng)拆箱,而后類型提升為long,因此結(jié)果為true
  6. g.equals(a+b) 由規(guī)則3,最終比較時(shí)為L(zhǎng)ong.equals(Integer),類型都不同,結(jié)果當(dāng)然為false

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

相關(guān)閱讀更多精彩內(nèi)容

  • 什么的拆裝箱 我第一次聽(tīng)到這個(gè)概念是一臉懵逼的,而其實(shí)最常使用的地方就是我們熟悉的包裝類的使用中.比如將int的變...
    _ALID閱讀 646評(píng)論 0 0
  • 在給部門做分享的時(shí)候,一位同學(xué)提問(wèn)說(shuō)一直沒(méi)搞明白Java的裝箱和拆箱,讓我給講解下,所以才有了下面這篇文章: 本次...
    嗨技術(shù)閱讀 604評(píng)論 1 2
  • 引入 == 基本數(shù)據(jù)類型(也稱原始數(shù)據(jù)類型) :byte,short,char,int,long,float,do...
    凱諾婷閱讀 1,311評(píng)論 1 7
  • 專業(yè)考題類型管理運(yùn)行工作負(fù)責(zé)人一般作業(yè)考題內(nèi)容選項(xiàng)A選項(xiàng)B選項(xiàng)C選項(xiàng)D選項(xiàng)E選項(xiàng)F正確答案 變電單選GYSZ本規(guī)程...
    小白兔去釣魚(yú)閱讀 10,579評(píng)論 0 13
  • 十八年寒窗苦讀,我曾拼了命的想要離開(kāi)那個(gè)生我養(yǎng)我的故鄉(xiāng),直到有一天異地而居,才知道自己對(duì)這方土地愛(ài)的深沉。背起...
    小眼睛的牛牛閱讀 428評(píng)論 3 5

友情鏈接更多精彩內(nèi)容