點擊上方「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的朋友能夠試試看哦~
推薦閱讀
2. 危險!80% 用戶正在考慮放棄 Oracle JDK…
3. 面試官問:Mybatis 框架下 SQL 注入攻擊的 3 種方式
回覆"谷谷」獲取 Java開發大型電商系統商城實戰視頻教程
好文點個在看吧!
本文分享自微信公衆號 - Java面試進化論(AuditionEvolution)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。