Java三目運(yùn)算中隱藏的自動(dòng)拆裝箱
最近修改線上bug的時(shí)候排查了一個(gè)十分隱藏的bug,直接上代碼:
Integer a = null; boolean flag = true; Integer b = flag ? a : 0;
乍一看是沒什么毛病的,但是已運(yùn)行就會(huì)發(fā)現(xiàn)報(bào)空指針,在idea里面也會(huì)警告可能有空指針,這是什么原因呢?
直接看字節(jié)碼:
0: aconst_null 1: astore_1 2: iconst_1 3: istore_2 4: iload_2 5: ifeq 15 8: aload_1 9: invokevirtual #2 // Method java/lang/Integer.intValue:()I 12: goto 16 15: iconst_0 16: invokestatic #3 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 19: astore_3 20: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream; 23: aload_3 24: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V 27: return
可以看到字節(jié)碼中調(diào)用了`Integer.valueOf()`
方法,因?yàn)槲覀兇a中一個(gè)值使用的是0(基本數(shù)據(jù)類型int),編譯器就會(huì)進(jìn)行自動(dòng)拆裝箱(成int),
雖然三目運(yùn)算的后面邏輯不會(huì)執(zhí)行,但是隱藏的自動(dòng)拆裝箱會(huì)執(zhí)行`Integer.valueOf()`方法,也就有了空指針異常。
為了進(jìn)一步驗(yàn)證存在自動(dòng)拆裝箱,把代碼修改一下:
Integer a = null; boolean flag = true; Integer b = flag ? a : new Integer(0);
再看字節(jié)碼:
0: aconst_null 1: astore_1 2: iconst_1 3: istore_2 4: iload_2 5: ifeq 12 8: aload_1 9: goto 20 12: new #2 // class java/lang/Integer 15: dup 16: iconst_0 17: invokespecial #3 // Method java/lang/Integer."<init>":(I)V 20: astore_3 21: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream; 24: aload_3 25: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
可以看到,由于重新創(chuàng)建了一個(gè)`Integer`對(duì)象,并沒有基本類型的存在,也就不存在自動(dòng)拆裝箱,修改過后的代碼也就不會(huì)有問題了,但是idea的警告依舊存在。
這是一個(gè)非常隱蔽,也非常容易忽略和踩坑的一個(gè)地方,三目運(yùn)算符的使用應(yīng)該保證后面的值都是常量,或者統(tǒng)一類型,不然就會(huì)出現(xiàn)上面的情況。
更甚三目運(yùn)算符本身提供的作用也不過是為了簡(jiǎn)化邏輯,在其中放入過多的邏輯判斷也就違背了其初衷。
總結(jié)
以上所述是小編給大家介紹的Java三目運(yùn)算中隱藏的自動(dòng)拆裝箱,希望對(duì)大家有所幫助,如果大家有任何疑問歡迎給我留言,小編會(huì)及時(shí)回復(fù)大家的!
相關(guān)文章
SpringCloud Feign參數(shù)問題及解決方法
這篇文章主要介紹了SpringCloud Feign參數(shù)問題及解決方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12SpringMVC源碼解析之消息轉(zhuǎn)換器HttpMessageConverter
本篇文章主要介紹了SpringMVC源碼解析之消息轉(zhuǎn)換器HttpMessageConverter ,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧2017-11-11win11?idea?shift+F6快捷鍵失效問題解決方案
這篇文章主要介紹了win11?idea?shift+F6快捷鍵失效問題,本文給大家分享最新解決方案,需要的朋友可以參考下2023-08-08SpringBoot多環(huán)境切換的配置實(shí)現(xiàn)
在日常的開發(fā)中,一般都會(huì)分好幾種環(huán)境,本文就來(lái)介紹一下SpringBoot多環(huán)境切換的配置實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03解析Spring中的靜態(tài)代理和動(dòng)態(tài)代理
學(xué)習(xí) Spring 的過程中,不可避免要掌握代理模式。這篇文章總結(jié)一下代理模式。顧名思義,代理,就是你委托別人幫你辦事,所以代理模式也有人稱作委托模式的。比如領(lǐng)導(dǎo)要做什么事,可以委托他的秘書去幫忙做,這時(shí)就可以把秘書看做領(lǐng)導(dǎo)的代理2021-06-06java使用Apache工具集實(shí)現(xiàn)ftp文件傳輸代碼詳解
這篇文章主要介紹了java使用Apache工具集實(shí)現(xiàn)ftp文件傳輸代碼詳解,分享了詳細(xì)連接ftp server和上傳文件,下載文件的代碼,以及結(jié)果展示,具有一定借鑒價(jià)值,需要的朋友可以參考下。2017-12-12