<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>

          這幾天研究了一下JDK14,發(fā)現(xiàn)它處理NPE的方式,真香!

          共 3163字,需瀏覽 7分鐘

           ·

          2021-04-17 13:34


          上一篇:深夜看了張一鳴的微博,讓我越想越后怕

          來源:鍋外的大佬

          在Java語言中,處理空指針往往是一件很頭疼的事情,一不小心,說不定就搞出個(gè)線上Bug,讓你的績效考核拿到3.25。

          最近,新出的Java14,相信大家都有所耳聞,那么今天就來看看,面對NullPointerException,Java14有哪些更好的處理方式呢?

          傳統(tǒng)的 NullPointerException


          我們編碼過程中呢,經(jīng)常會使用鏈?zhǔn)秸{(diào)用的方式來寫代碼,這樣寫起來很方便,也很清晰,但是,一旦出現(xiàn)NullPointerException,那就頭大了,因?yàn)槟愫茈y知道異常是在什么時(shí)候開始發(fā)生的。

          舉個(gè)簡單的例子,就比如下面的代碼,要找到公司某個(gè)員工的戶籍所在地,我們這樣來調(diào)用

          String city = employee.getDetailInfos().getRegistryAddress().getCity();
          在鏈?zhǔn)秸{(diào)用的過程中,如果employee, getDetailInfos(),或者 getRegistryAddress() 為空,JVM就會拋出 NullPointerException。

          那么導(dǎo)致異常的根本原因是什么?如果不使用調(diào)試器,很難確定哪個(gè)變量為空。而且,JVM也只會打印導(dǎo)致異常的方法、文件名和行號,僅此而已。那么下面,我將帶大家了解Java 14如何通過 JEP 358 解決這個(gè)問題。

          增強(qiáng)型 NullPointerException


          SAP在2006年為其商業(yè)JVM實(shí)現(xiàn)了增強(qiáng)型的 NullPointerException。2019年2月,它被提議作為OpenJDK社區(qū)的一個(gè)增強(qiáng),之后很快,它成為了一個(gè)JEP。所以,該功能在2019年10月完成并在JDK 14版本推出。

          本質(zhì)上,JEP 358 旨在通過描述某個(gè)變量是 “null” 來提高 JVM 生成的 “NullPointerException” 的可讀性。JEP 358通過在方法、文件名和行號旁邊描述為 null 的變量,帶來了一個(gè)詳細(xì)的 NullPointerException 消息。它通過分析程序的字節(jié)碼指令來工作。因此,它能夠精確地確定哪個(gè)變量或表達(dá)式是null。最重要的是,JDK 14中默認(rèn)關(guān)閉詳細(xì)的異常消息。要啟用它,我們需要使用命令行選項(xiàng):

          -XX:+ShowCodeDetailsInExceptionMessages

          詳細(xì)的異常信息

          考慮在激活 ShowCodeDetailsInExceptionMessages 標(biāo)志的情況下再次運(yùn)行代碼:

          Exception in thread "main" java.lang.NullPointerException:  Cannot invoke "RegistryAddress.getCity()" because the return value of"com.developlee.java14.helpfulnullpointerexceptions.HelpfulNullPointerException$DetailInfos.getRegistryAddress()" is null  at com.developlee.java14.helpfulnullpointerexceptions.HelpfulNullPointerException.main(HelpfulNullPointerException.java:10)

          這一次,從附加信息中,我們知道員工的個(gè)人詳細(xì)信息丟失的注冊地址導(dǎo)致了我們的異常。從這個(gè)增強(qiáng)中獲得的信息可以節(jié)省我們調(diào)試所用的時(shí)間。

          JVM由兩部分組成詳細(xì)的異常消息。第一部分表示失敗的操作,這是引用為 *null* 的結(jié)果,而第二部分標(biāo)識了 *null* 引用的原因:

          Cannot invoke "String.toLowerCase()" because the return value of "getEmailAddress()" is null

          為了生成異常消息,JEP 358 重構(gòu)了將空引用推送到操作數(shù)堆棧上的部分源代碼。

          技術(shù)方面


          現(xiàn)在我們已經(jīng)很好地理解了如何使用增強(qiáng)的NullPointerExceptions標(biāo)識 null 引用,讓我們來看看它的一些技術(shù)方面。

          首先,只有當(dāng)JVM本身拋出一個(gè) NullPointerException 時(shí),才會進(jìn)行詳細(xì)的消息計(jì)算,如果我們在Java代碼中顯式拋出異常,則不會執(zhí)行計(jì)算。原因是因?yàn)椋涸谶@些情況下,很可能已經(jīng)在異常構(gòu)造函數(shù)中傳遞了一條有意義的消息。

          其次,JEP 358懶漢式地計(jì)算消息,這意味著只有當(dāng)我們打印異常消息時(shí)才調(diào)用增強(qiáng)的NullPointerException,而不是當(dāng)異常發(fā)生時(shí)就調(diào)用。因此,對于通常的JVM流程不應(yīng)該有任何性能影響,在那里我們可以捕獲并重新拋出異常,因?yàn)樵鄄⒉粫幌氪蛴‘惓Oⅰ?/span>

          最后,詳細(xì)的異常消息可能包含源代碼中的局部變量名。因此,我們可以認(rèn)為這是一個(gè)潛在的安全風(fēng)險(xiǎn)。但是,只有在運(yùn)行使用激活的 -g 標(biāo)記編譯的代碼時(shí),才會發(fā)生這種情況,該標(biāo)記會生成調(diào)試信息并將其添加到類文件中。請考慮一個(gè)簡單的示例,我們已編譯該示例以包含以下附加調(diào)試信息:

          Employee employee = null;employee.getName();
          當(dāng)執(zhí)行以上代碼時(shí),異常信息中會打印本地變量名稱:
          "com.developlee.java14.helpfulnullpointerexceptions.HelpfulNullPointerException$Employee.getName()"because "employee" is null

          相反,在沒有額外調(diào)試信息的情況下,JVM 只提供它在詳細(xì)消息中所知道的變量:

          Cannot invoke"com.developlee.java14.helpfulnullpointerexceptions.HelpfulNullPointerException$Employee.getName()"because "<local1>" is null

          JVM 打印編譯器分配的變量索引,而不是本地變量名(employee)。


          關(guān)于NullPointerException的處理到這里就結(jié)束了,通過Java14增強(qiáng)的NullPointerException,我們可以很快速的定位代碼問題的原因所在,更快的調(diào)試代碼,節(jié)約時(shí)間,提高效率。

          已經(jīng)安裝了Java14的朋友可以試試看哦~



          感謝您的閱讀,也歡迎您發(fā)表關(guān)于這篇文章的任何建議,關(guān)注我,技術(shù)不迷茫!小編到你上高速。


              · END ·
          最后,關(guān)注公眾號互聯(lián)網(wǎng)架構(gòu)師,在后臺回復(fù):2T,可以獲取我整理的 Java 系列面試題和答案,非常齊全


          正文結(jié)束


          推薦閱讀 ↓↓↓

          1.不認(rèn)命,從10年流水線工人,到谷歌上班的程序媛,一位湖南妹子的勵志故事

          2.如何才能成為優(yōu)秀的架構(gòu)師?

          3.從零開始搭建創(chuàng)業(yè)公司后臺技術(shù)棧

          4.程序員一般可以從什么平臺接私活?

          5.37歲程序員被裁,120天沒找到工作,無奈去小公司,結(jié)果懵了...

          6.IntelliJ IDEA 2019.3 首個(gè)最新訪問版本發(fā)布,新特性搶先看

          7.漫畫:程序員相親圖鑒,笑屎我了~

          8.15張圖看懂瞎忙和高效的區(qū)別!

          一個(gè)人學(xué)習(xí)、工作很迷茫?


          點(diǎn)擊「閱讀原文」加入我們的小圈子!

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

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(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>
                  性久久久久久久久久久久 | 国产精品久久7777 | 伊人网大香蕉 | 亚洲欧洲视频在线观看 | 五月丁香乱能高清 |