1. 程式人生 > >Java 14 來勢洶洶,這回讓空指標無處遁形!!

Java 14 來勢洶洶,這回讓空指標無處遁形!!

上篇:Java 14 之模式匹配,非常讚的一個新特性!

相信在坐的每一位 Java 程式設計師都遇到過空指標異常: NullPointerException(NPE),不甚其煩。

棧長之前也分享幾篇避免空指標的文章:

  • 別再寫 bug 了,避免空指標的 5 個案例!
  • 沒用 Java 8,怎麼優雅地避免空指標?

空指標異常神鬼莫測,它幾乎可以出現在程式中的任何位置,想嘗試捕獲處理是不太切實際的。

背景

我們一般要通過 JVM 異常報告的程式碼位置去處理,JVM 會打印出導致空指導異常的詳細類名、方法名以及行號,如以下異常所示:

Exception in thread "main" java.lang.NullPointerException
    at Test.main(Test.java:3)

很顯然,Test 類的 main 方法第 3 行發生了空指標異常,如果第 3 行的程式碼是:

javastack.name = '棧長';

這時候我們肯定能判定 javastack 物件為 null,如果是下面這段呢:

javastack.name = params.user.name;

以下這 e 個物件都可能為空:

  • javastack
  • params
  • user

這時候就無法通過 JVM 報告的位置所判定到底是哪個變數為空了,每一個物件都可能是空指標的入口,只能通過輸出日誌或者 Debug 除錯去跟蹤了。

如果 JVM 可以提供足夠明確的資訊以顯示空指標異常的具體來源,而無需額外的程式碼、工具來定位,那麼這對開發人員、或者線上問題定位都舉足輕重。當然,這個在商業 JVM 早就做到了,Java 14,它現在也終於來了。

詳細的空指標異常資訊

詳細可以看官方這篇介紹:

https://openjdk.java.net/jeps/358

Exception in thread "main" java.lang.NullPointerException: 
        Cannot read field "name" because "params.user" is null
    at Test.main(Test.java:3)

如上所示,會給出詳細的發生空指標異常變數路徑。

另外,如果是下標式訪問的賦值語句,如 a[i][j][k] = 2020; 丟擲空指標,那會是這樣的:

Exception in thread "main" java.lang.NullPointerException:
        Cannot load from object array because "a[i][j]" is null
    at Test.main(Test.java:18)

注意:在同一行上顯示異常型別、異常訊息會導致行很長,所以為了保持可讀性,會在第二行顯示詳細異常資訊。

另外,這個功能在 Java 14 預設情況下是不開啟的,可以使用以下 JVM 引數進行切換:

開啟:-XX:+ShowCodeDetailsInExceptionMessages

關閉:-XX:-ShowCodeDetailsInExceptionMessages

為什麼現在預設不開啟?

1)效能

如果應用程式頻繁地丟擲並列印異常堆疊訊息,勢必會帶來一定的開銷、影響效能,所以應儘量避免這種開銷。

2)安全

這個會導致更多原始碼的暴露,如果這個不能接受,則不應由 JVM 配置應用程式列印,而應捕獲並丟棄。

3)相容性

過去的 JDK 都是不列印詳細空指標異常資訊的,JVM 相關工具要依賴於異常訊息的準確格式,有可能會存在相容性問題。

所以,這個特性暫時預設是關閉的,在未來不久的版本中會預設開啟。

好了,今天就到這了,關注微信公眾號:Java技術棧,新特性實戰陸續更新中,公眾號第一時間推送。歷史 Java 8 - 14 新特性教程可以在公眾號回覆 java 獲取。

棧長原創和整理不易,覺得文章不錯,在看、轉發分享給更多的朋友們,總能幫助有需要的人,大家一起流弊~

推薦去我的部落格閱讀更多:

1.Java JVM、集合、多執行緒、新特性系列教程

2.Spring MVC、Spring Boot、Spring Cloud 系列教程

3.Maven、Git、Eclipse、Intellij IDEA 系列工具教程

4.Java、後端、架構、阿里巴巴等大廠最新面試題

覺得不錯,別忘了點贊+轉發哦!