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

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


相信在坐的每一位 Java 程序員都遇到過空指針異常:NullPointerException(NPE),不甚其煩。

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

背景

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

<code>

Exception

 

in

 

thread

 "

main

java

.lang

.NullPointerException

    

at

 

Test

.main

(

Test

.java

:3)

/<code>

很顯然,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

<code>

Exception

 

in

 

thread

 "

main

java

.lang

.NullPointerException

:          

Cannot

 

read

 

field

 "

name

because

 "

params

.user

is

 

null

    

at

 

Test

.main

(

Test

.java

:3)

/<code>

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

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

<code>Exception in thread "main" java.lang.NullPointerException:
        Cannot load from object array because "a[

i

][

j

]" is null     at Test.main(Test.java:18)/<code>

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

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

開啟:-XX:+ShowCodeDetailsInExceptionMessages

關閉:-XX:-ShowCodeDetailsInExceptionMessages

為什麼現在默認不開啟?

1)性能

如果應用程序頻繁地拋出並打印異常堆棧消息,勢必會帶來一定的開銷、影響性能,所以應儘量避免這種開銷。

2)安全

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

3)兼容性

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

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

好了,今天就到這了,關注我,新特性實戰陸續更新中


分享到:


相關文章: