NullPointerException 的處理新方式, Java14 真的太香了!

點擊上方「Java面試進化論」,選擇「設爲星標java

回覆」666「獲取新整理的面試資料web

來源:鍋外的大佬面試


  • 1.傳統的 NullPointerException
  • 2.加強型 NullPointerException
    • 2.1 詳細的異常信息
  • 3. 技術方面

在Java語言中,處理空指針每每是一件很頭疼的事情,一不當心,說不定就搞出個線上Bug,讓你的績效考覈拿到3.25。安全

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

1.傳統的 NullPointerException

咱們編碼過程當中呢,常常會使用鏈式調用的方式來寫代碼,這樣寫起來很方便,也很清晰,可是,一旦出現NullPointerException,那就頭大了,由於你很難知道異常是在何時開始發生的。app

舉個簡單的例子,就好比下面的代碼,要找到公司某個員工的戶籍所在地,咱們這樣來調用框架

String city = employee.getDetailInfos().getRegistryAddress().getCity();

在鏈式調用的過程當中,若是employee, getDetailInfos(),或者 getRegistryAddress() 爲空,JVM就會拋出 NullPointerException編輯器

那麼致使異常的根本緣由是什麼?若是不使用調試器,很難肯定哪一個變量爲空。並且,JVM也只會打印致使異常的方法、文件名和行號,僅此而已。那麼下面,我將帶你們瞭解Java 14如何經過 JEP 358 解決這個問題。函數

2.加強型 NullPointerException

SAP在2006年爲其商業JVM實現了加強型的 NullPointerException。2019年2月,它被提議做爲OpenJDK社區的一個加強,以後很快,它成爲了一個JEP。因此,該功能在2019年10月完成並在JDK 14版本推出性能

本質上,JEP 358 旨在經過描述某個變量是 「null」 來提升 JVM 生成的 「NullPointerException」 的可讀性。JEP 358經過在方法、文件名和行號旁邊描述爲 null 的變量,帶來了一個詳細的 NullPointerException 消息。它經過分析程序的字節碼指令來工做。所以,它可以精確地肯定哪一個變量或表達式是null。最重要的是,JDK 14中默認關閉詳細的異常消息。要啓用它,咱們須要使用命令行選項:

-XX:+ShowCodeDetailsInExceptionMessages

2.1 詳細的異常信息

考慮在激活 ShowCodeDetailsInExceptionMessages 標誌的狀況下再次運行代碼:

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)

這一次,從附加信息中,咱們知道員工的我的詳細信息丟失的註冊地址致使了咱們的異常。從這個加強中得到的信息能夠節省咱們調試所用的時間。

JVM由兩部分組成詳細的異常消息。第一部分表示失敗的操做,這是引用爲 *null* 的結果,而第二部分標識了 *null* 引用的緣由:

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

爲了生成異常消息,JEP 358 重構了將空引用推送到操做數堆棧上的部分源代碼。

3. 技術方面

如今咱們已經很好地理解了如何使用加強的NullPointerExceptions標識 null 引用,讓咱們來看看它的一些技術方面。

首先,只有當JVM自己拋出一個 NullPointerException 時,纔會進行詳細的消息計算,若是咱們在Java代碼中顯式拋出異常,則不會執行計算。緣由是由於:在這些狀況下,極可能已經在異常構造函數中傳遞了一條有意義的消息。

其次,**JEP 358 ** 懶漢式地計算消息,這意味着只有當咱們打印異常消息時才調用加強的NullPointerException,而不是當異常發生時就調用。所以,對於一般的JVM流程不該該有任何性能影響,在那裏咱們能夠捕獲並從新拋出異常,由於咱並不會只想打印異常消息。

最後,詳細的異常消息可能包含源代碼中的局部變量名。所以,咱們能夠認爲這是一個潛在的安全風險。可是,只有在運行使用激活的 -g 標記編譯的代碼時,纔會發生這種狀況,該標記會生成調試信息並將其添加到類文件中。請考慮一個簡單的示例,咱們已編譯該示例以包含如下附加調試信息:

Employee employee = null;
employee.getName();

當執行以上代碼時,異常信息中會打印本地變量名稱:

"com.developlee.java14.helpfulnullpointerexceptions.HelpfulNullPointerException$Employee.getName()"
because "employee" is null

相反,在沒有額外調試信息的狀況下,JVM 只提供它在詳細消息中所知道的變量:

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

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

關於NullPointerException的處理到這裏就結束了,經過Java14加強的NullPointerException,咱們能夠很快速的定位代碼問題的緣由所在,更快的調試代碼,節約時間,提升效率。

已經安裝了Java14的朋友能夠試試看哦~

    
  
      
      
       
       
                
       
  
      

1.  一條Select的自述!這不就是「你」的一輩子嗎!

2.  危險!80% 用戶正在考慮放棄 Oracle JDK…

3.  面試官問:Mybatis 框架下 SQL 注入攻擊的 3 種方式

4.  華爲阿里下班時間曝光:全部的光鮮,都有加班的味道

5.  工做發狂:Mybatis 中$和#千萬不要亂用!


               
                   
                   
                    
                    
                             
                    
               
                   
回覆"谷谷」獲取

Java開發大型電商系統商城實戰視頻教程


              
                  
                  
                   
                   
                            
                   
              
                  
好文點個在看吧!

本文分享自微信公衆號 - Java面試進化論(AuditionEvolution)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索