NullPointerException 是Java 程式碼中最常見的例外,我將其最可能出現的場景歸為以下5 種:
參數值是Integer 等包裝類型,使用時因為自動拆箱出現了空白指標例外;
字串比較出現空指標例外;
- ##諸如ConcurrentHashMap 這樣的容器不支援Key 和Value 為null,強行put null 的Key 或Value 會出現空指標異常;
- A 物件包含了B,在透過A 物件的欄位取得B 之後,沒有對欄位判空就級聯呼叫B 的方法出現空指標異常;方法或遠端服務回傳的List 不是空而是null,沒有進行判空就直接呼叫List 的方法出現空指標異常。
private List<String> wrongMethod(FooService fooService, Integer i, String s, String t) { log.info("result {} {} {} {}", i + 1, s.equals("OK"), s.equals(t), new ConcurrentHashMap<String, String>().put(null, null)); if (fooService.getBarService().bar().equals("OK")) log.info("OK"); return null; } @GetMapping("wrong") public int wrong(@RequestParam(value = "test", defaultValue = "1111") String test) { return wrongMethod(test.charAt(0) == '1' ? null : new FooService(), test.charAt(1) == '1' ? null : 1, test.charAt(2) == '1' ? null : "OK", test.charAt(3) == '1' ? null : "OK").size(); } class FooService { @Getter private BarService barService; } class BarService { String bar() { return "OK"; } }修正想法如下:
- #對於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 的話一行程式碼就夠了。
- 對於rightMethod 傳回的List,由於無法確認其是否為null,所以在呼叫size 方法獲得清單大小之前,同樣可以使用Optional.ofNullable 包裝一下傳回值,然後透過. orElse(Collections.emptyList()) 實作在List 為null 的時候得到一個空的List,最後再呼叫size 方法。
private List<String> rightMethod(FooService fooService, Integer i, String s, String t) { log.info("result {} {} {} {}", Optional.ofNullable(i).orElse(0) + 1, "OK".equals(s), Objects.equals(s, t), new HashMap<String, String>().put(null, null)); Optional.ofNullable(fooService) .map(FooService::getBarService) .filter(barService -> "OK".equals(barService.bar())) .ifPresent(result -> log.info("OK")); return new ArrayList<>(); } @GetMapping("right") public int right(@RequestParam(value = "test", defaultValue = "1111") String test) { return Optional.ofNullable(rightMethod(test.charAt(0) == '1' ? null : new FooService(), test.charAt(1) == '1' ? null : 1, test.charAt(2) == '1' ? null : "OK", test.charAt(3) == '1' ? null : "OK")) .orElse(Collections.emptyList()).size(); }
- 我們根據業務需求分別對姓名、年齡和暱稱進行更新:對於姓名,我們認為客戶端傳null 是希望把姓名重設為空,允許這樣的操作,使用Optional 的orElse 方法一鍵把空轉換為空字串即可。
- 對於年齡,我們認為如果客戶端希望更新年齡就必須傳一個有效的年齡,年齡不存在重置操作,可以使用Optional 的orElseThrow 方法在值為空的時候拋出IllegalArgumentException。
- 對於暱稱,因為資料庫中姓名不可能為 null,所以可以放心地把暱稱設為 guest 加上資料庫取出的姓名。
@PostMapping("right") public UserEntity right(@RequestBody UserDto user) { if (user == null || user.getId() == null) throw new IllegalArgumentException("用户Id不能为空"); UserEntity userEntity = userEntityRepository.findById(user.getId()) .orElseThrow(() -> new IllegalArgumentException("用户不存在")); if (user.getName() != null) { userEntity.setName(user.getName().orElse("")); } userEntity.setNickname("guest" + userEntity.getName()); if (user.getAge() != null) { userEntity.setAge(user.getAge().orElseThrow(() -> new IllegalArgumentException("年龄不能为空"))); } return userEntityRepository.save(userEntity); }
以上是Java中如何處理空指標異常的詳細內容。更多資訊請關注PHP中文網其他相關文章!
陳述
本文轉載於:亿速云。如有侵權,請聯絡admin@php.cn刪除

在使用IntelliJIDEAUltimate版本啟動Spring...

在使用MyBatis-Plus或其他ORM框架進行數據庫操作時,經常需要根據實體類的屬性名構造查詢條件。如果每次都手動...

Redis緩存方案如何實現產品排行榜列表的需求?在開發過程中,我們常常需要處理排行榜的需求,例如展示一個�...

將姓名轉換為數字以實現排序的解決方案在許多應用場景中,用戶可能需要在群組中進行排序,尤其是在一個用...

電商平台SKU和SPU表設計詳解本文將探討電商平台中SKU和SPU的數據庫設計問題,特別是如何處理用戶自定義銷售屬...

在Idea中如何設置SpringBoot項目默認運行配置列表在使用IntelliJ...


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章
刺客信條陰影:貝殼謎語解決方案
3 週前ByDDD
Windows 11 KB5054979中的新功能以及如何解決更新問題
2 週前ByDDD
在哪裡可以找到原子中的起重機控制鑰匙卡
3 週前ByDDD
刺客信條陰影 - 如何找到鐵匠,解鎖武器和裝甲定制
4 週前ByDDD
<🎜>:死鐵路 - 如何完成所有挑戰
3 週前ByDDD

熱工具

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

禪工作室 13.0.1
強大的PHP整合開發環境

WebStorm Mac版
好用的JavaScript開發工具

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。