<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          不是吧,還有人不知道三目運(yùn)算符的BUG

          共 2495字,需瀏覽 5分鐘

           ·

          2021-04-13 03:18

          前言

          文本已收錄至我的GitHub倉庫,歡迎Star:https://github.com/bin392328206/six-finger
          種一棵樹最好的時(shí)間是十年前,其次是現(xiàn)在
          我知道很多人不玩qq了,但是懷舊一下,歡迎加入六脈神劍Java菜鳥學(xué)習(xí)群,群聊號碼:549684836 鼓勵(lì)大家在技術(shù)的路上寫博客

          周末快樂,送大家一句話

          這世上每個(gè)人都背負(fù)著枷鎖,有的人是別人給的,有的是自己給的。

          絮叨

          三目運(yùn)算符一直是眾多開發(fā)者信手拈來的一種寫法,它簡化了if-else的臃腫的寫法,而是用一行代碼替代,就感覺無形之中秀了一把。殊不知,這么帥氣的代碼也暗藏著一個(gè)BUG。

          緣由

          頭天晚上發(fā)布了一個(gè)功能,本以為是波瀾不驚的一個(gè)需求,結(jié)果第二天kibana打出了成噸的NPE日志。這些NPE日志大多都不約而同都指向了我寫的一行代碼,我立馬推了下我的眼鏡,開始排查起來了。

          問題代碼

          Kibana的堆棧日志定位在第899行。

          resultMap.put("unAuditPurchaseOrder", switchConf == null ? 0 : switchConf.getUnAuditPurchaseOrder());

          1.檢查了resultMap,它在上面有實(shí)例化,不可能為空。2.檢查switchConf,但是在這里有判空,也不會報(bào)錯(cuò)。那是怎么回事????

          繼續(xù)排查

          既然肉眼看不出,那么只能找一臺測試機(jī),用一下Arthas看一下具體的情況。(線上慎用,因?yàn)榭赡軙斐煽D)

          trace com.raycloud.dmj.tj.services.customer.CustomerButtonService getPurchaseConfig -n 5 '1==1' --skipJDKMethod false

          果然,這里就發(fā)現(xiàn)了端倪。這里竟然執(zhí)行了intValue()!也就是說如果switchConf.getUnAuditPurchaseOrder()這個(gè)是null,那么就很明顯發(fā)生了NPE。

          看一下字節(jié)碼

          為了顯現(xiàn)效果,我換一個(gè)簡單的程序

          public class Test {

              public static void main(String[] args) {

                  Integer i = null;
                  System.out.println(1 != 1 ? 0 : i);

              }
          }

          定位到class文件目錄,執(zhí)行

          javap -c -l Test

          然后我又改了一下程序

          public class Test {

              public static void main(String[] args) {

                  Integer i = null;
                  System.out.println(1 == 1 ? 0 : i);

              }
          }

          這次運(yùn)行并不會報(bào)錯(cuò),看一下它的JVM指令:

          因?yàn)槿窟\(yùn)算符的結(jié)果是前者的邏輯,即返回一個(gè)常量0。

          解釋

          由上面的實(shí)驗(yàn)可以發(fā)現(xiàn),JVM在解釋三目運(yùn)算符的時(shí)候,會對兩個(gè)邏輯語句進(jìn)行數(shù)據(jù)類型校驗(yàn),按照前者的數(shù)據(jù)類型為準(zhǔn)。實(shí)驗(yàn)中,數(shù)據(jù)類型是基本數(shù)據(jù)類型,所以,如果邏輯走到了后者,那么就會進(jìn)行自動(dòng)的拆箱。這個(gè)隱式的操作就是造成這個(gè)BUG的原因。

          解決

          既然知道原因了,那么只要統(tǒng)一數(shù)據(jù)類型就行:

          public class Test {

              public static void main(String[] args) {

                  Integer i = null;
                  System.out.println(1 != 1 ? new Integer(0) : i);

              }
          }

          然后按照慣例,我們還是看一下他的JVM指令:

          拾遺

          后來在無意之中發(fā)現(xiàn),原來這個(gè)例子在《阿里巴巴開發(fā)手冊》當(dāng)中也有被記錄

          其實(shí)說的也是一回事情!

          結(jié)尾

          文章出自掘金 浮沉_fuchen

          日常求贊

          好了各位,以上就是這篇文章的全部內(nèi)容了,能看到這里的人呀,都是真粉

          創(chuàng)作不易,各位的支持和認(rèn)可,就是我創(chuàng)作的最大動(dòng)力,我們下篇文章見

          六脈神劍 | 文 如果本篇博客有任何錯(cuò)誤,請批評指教,不勝感激 !


          瀏覽 62
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          ??迌?nèi)说哪渴?/a>
          ??迌?nèi)说哪渴?/a>
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美亚洲一级黄片 | 日韩三级片在线观看视频 | 付妙菱 女大学生羞涩 | 特级西西人体4444XXXX | 欧洲亚洲在线 |