天天看點

JDK 14的新特性:更加好用的NullPointerExceptions

JDK 14的新特性:更加好用的NullPointerExceptions

讓99%的java程式員都頭痛的異常就是NullPointerExceptions了。NullPointerExceptions簡稱NPE,它是運作時異常的一種,也是java程式中最最容易出現的異常。

出現了NullPointerExceptions之後我們怎麼處理呢?

一般情況下就是看日志,看一下到底哪一行出錯了。如果這一行隻有簡單的代碼,那麼很容易就找到問題所在。

要命的是如果這一行很複雜,那麼找出問題就不是那麼容易了。很有可能我們需要向前debug100行,向後debug50行才能解決。

最大的問題就是如果這個異常出現線上上環境,debug是不可能debug了。這時候就要靠你的肉眼,你對程式的敏感程度再加上你的專業素養,才能從萬花叢中找出那個問題。

舉個例子,我們定義一個CustUser和Address:

@Data
public class CustUser {
    private String userName;
    private Address address;
}      
@Data
public class Address {
    private String addressName;
}      

再來産生一個NPE:

@Slf4j
public class NPEUsage {

    public static void main(String[] args) {
        Address address=new Address();
        CustUser custUser=new CustUser();
        custUser.setAddress(address);
        log.info(custUser.getAddress().getAddressName().toLowerCase());
    }
}      

上面代碼中的最後一行,因為addressName是空的,是以在調用toLowerCase的時候會抛出NPE。運作結果如下:

Exception in thread "main" java.lang.NullPointerException
  at com.flydean.nullpointerexceptions.NPEUsage.main(NPEUsage.java:16)      

上述異常隻告訴我們有一個NPE在第16行。但是16行有一長串代碼,到底是哪裡報了這個異常呢?

簡單代碼,比如上面我們提的例子,簡單分析一下就知道問題所在了。但是對于那麼猶如蛛網一樣的複雜的項目,找起來就很難了。

别害怕,JEP 358: Helpful NullPointerExceptions就是用來解決這個問題。

還是上面的例子,還是上面的配方和味道,我們隻需要在運作時加上下面的參數:

-XX:+ShowCodeDetailsInExceptionMessages      
JDK 14的新特性:更加好用的NullPointerExceptions

運作一下:

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.toLowerCase()" because the return value of "com.flydean.nullpointerexceptions.Address.getAddressName()" is null
  at com.flydean.nullpointerexceptions.NPEUsage.main(NPEUsage.java:16)      

看到不同之處了嗎?完整的出錯資訊被列印出來了。你苦思冥想的問題解決了。

這個特性好是好,但是預設情況下是被關閉的。

有利就有弊,我們看下這個參數有什麼影響:

  1. 性能影響:因為要存儲額外的資訊,對 stack trace會有性能上面的壓力。
  2. 安全影響:從上面的例子我們可以看到異常資訊中包含了非常充分的代碼資訊内容。如果對一些機密應用,完全可以通過異常資訊來推斷代碼邏輯。進而對安全性造成影響。
  3. 相容性:最後是相容性,之前的JVM可沒有存儲這些額外的NPE資訊,是以可能會有相容性的問題。

本文的例子​​https://github.com/ddean2009/learn-java-base-9-to-20