NullPointerException是Java代碼中最常見的異常,我將其最可能出現的場景歸爲以下5種:
- 參數值是Integer等包裝類型,使用時因爲自動拆箱出現了空指針異常;
- 字符串比較出現空指針異常;
- 諸如ConcurrentHashMap這樣的容器不支持Key和Value爲null,強行put
null的Key或Value會出現空指針異常;
- A對象包含了B,在通過A對象的字段獲得B之後,沒有對字段判空就級聯調用B的方法出現空指針異常;
- 方法或遠程服務返回的List不是空而是null,沒有進行判空就直接調用List的方法出現空指針異常
修復思路:
- 對於Integer的判空,可以使用Optional.ofNullable來構造一個Optional,然後使用orElse(0)把null替換爲默認值再進行+1操作。
- 對於String和字面量的比較,可以把字面量放在前面,比如"OK".equals(s),這樣即使s是null也不會出現空指針異常;而對於兩個可能爲 null的字符串變量的equals比較,可以使用Objects.equals,它會做判空處理。
- 對於ConcurrentHashMap,既然其Key和Value都不支持null,修復方式就是不要把null存進去。HashMap的Key和Value可以存入
null,而ConcurrentHashMap看似是HashMap的線程安全版本,卻不支持null值的Key和Value,這是容易產生誤區的一個地方。
- 對於類似fooService.getBarService().bar().equals(“OK”)的級聯調用,需要判空的地方有很多,包括fooService、getBarService()方
法的返回值,以及bar方法返回的字符串。如果使用if-else來判空的話可能需要好幾行代碼,但使用Optional的話一行代碼就夠了。
Optional.ofNullable(fooService)
.map(FooService::getBarService)
.filter(barService -> "OK".equals(barService.bar()))
.ifPresent(result -> log.info("OK"));
- 對於rightMethod返回的List,由於不能確認其是否爲null,所以在調用size方法獲得列表大小之前,同樣可以使用Optional.ofNullable
包裝一下返回值,然後通過.orElse(Collections.emptyList())實現在List爲null的時候獲得一個空的List,最後再調用size方法。
Optional.ofNullable(list).orElse(Collections.emptyList()).size()