一文教你掌握Java如何實現(xiàn)判空
1、前言
實際項目中我們會有很多地方需要判空校驗,如果不做判空校驗則可能產(chǎn)生NullPointerException異常。
針對異常的處理我們在上一篇有提及:
先來看一下實際項目中一些判空方式
if (ObjectUtil.isNotNull(vo.getSubmitterId())) { userIds.add(vo.getSubmitterId()); } if (StringUtils.isNotBlank(vo.getBudgetPM())) { userIds.add(Long.valueOf(vo.getBudgetPM())); } if (CollUtil.isNotEmpty(vo.getOriginatorList())) { userIds.addAl1(vo.getOriginatorList().stream(); }
通常我們判斷一個對象是否為Null,可以使用java.util中的Objects.nonNull(obj)、hutool中的ObjectUtil或者直接 null != obj
2、List的判空
像List這種比較特殊的在項目中可能不僅僅是判斷非空了。對于List來說不等于null和List.size()不等于0是兩回事,公司也有實習生常常有把這兩個混淆的情況,list不等于null說明已經(jīng)初始化了,堆內(nèi)存中有一塊屬于它的地盤,而size為0說明還沒往里面放東西,舉個例子說就是不等于null代表我現(xiàn)在有個瓶子,size大于0說明我向瓶子里裝水了。
實際項目中也發(fā)現(xiàn)有直接用list.isEmpty()去判斷的,來看一下源碼:
public boolean isEmpty() { return size == 0; }
相當于判斷瓶子里有沒有水(前提是瓶子已經(jīng)存在,若瓶子不存在,則會拋出NullPointerException異常)。
所以通常情況下會連用list != null && list.size > 0 來判斷,或者直接使用HuTool中CollUtil工具的isEmpty。諸如此類的還有Set、Map等
3、String的判空
這里還是用瓶子與水的概念,String為null時調(diào)用equals(String) 或 length() 等操作拋出 java.lang.NullPointerException。
針對字符串判空有以下幾種方式:
1、大多數(shù)人使用的方法之一,直觀,方便,但效率低下:
if(a == null || a.equals(""));
2、比較字符串長度,高效:
if(a == null || a.length() == 0);
3、Java SE 6.0 才剛剛開始提供,效率和方法二差不多:
if(a == null || a.isEmpty());
當然還可以使用org.apache.commons.lang.StringUtils工具。
StringUtils.isNotBlank(a);
* StringUtils.isNotBlank(null) = false
* StringUtils.isNotBlank("") = false
* StringUtils.isNotBlank(" ") = false
* StringUtils.isNotBlank("bob") = true
* StringUtils.isNotBlank(" bob ") = true
該工具類中還有個isNotEmpty()方法,從注釋可以很明顯看出二者的差別
StringUtils.isNotEmpty(a);
* StringUtils.isNotEmpty(null) = false
* StringUtils.isNotEmpty("") = false
* StringUtils.isNotEmpty(" ") = true
* StringUtils.isNotEmpty("bob") = true
* StringUtils.isNotEmpty(" bob ") = true
4、Optional
Optional的出現(xiàn)就是用來防止NullpointException的。常見的方法有:
- .empty():創(chuàng)建一個空的Optional實例
- .of(T t) : 創(chuàng)建一個Optional 實例,為null時報異常
- .ofNullable(T t):若t 不為null,創(chuàng)建Optional 實例,否則創(chuàng)建空實例
- isPresent() : 判斷容器中是否有值
- ifPresent(Consume lambda) :容器若不為空則執(zhí)行括號中的Lambda表達式
- orElse(T t) : 獲取容器中的元素,若容器為空則返回括號中的默認值
- orElseGet(Supplier s) :如果調(diào)用對象包含值,返回該值,否則返回s 獲取的值
- orElseThrow() :如果為空,就拋出定義的異常,如果不為空返回當前對象
- map(Function f): 如果有值對其處理,并返回處理后的Optional,否則返回Optional.empty()
- flatMap(Function mapper):與map 類似,要求返回值必須是Optional
- T get() :獲取容器中的元素,若容器為空則拋出NoSuchElement異常
先看個常見的示例:
baseInfo類中有布爾類型的屬性,是空返回false,不為空取其值,需要四行。
boolean blind = false; if (null != baseInfo.getBlind()){ blind = baseInfo.getBlind(); }
當使用Optional時,一行搞定,非常的優(yōu)雅。
boolean blind = Optional.ofNullable(baseInfo.getBlind()).orElse( other: false);
4.1 Optional對象的創(chuàng)建
public final class Optional<T> { private static final Optional<?> EMPTY = new Optional<>(); private final T value; //可以看到兩個構造方格都是private 私有的 //說明 沒辦法在外面new出來Optional對象 private Optional() { this.value = null; } private Optional(T value) { this.value = Objects.requireNonNull(value); } //這個靜態(tài)方法大致 是創(chuàng)建出一個包裝值為空的一個對象因為沒有任何參數(shù)賦值 public static<T> Optional<T> empty() { @SuppressWarnings("unchecked") Optional<T> t = (Optional<T>) EMPTY; return t; } //這個靜態(tài)方法大致 是創(chuàng)建出一個包裝值非空的一個對象 因為做了賦值 public static <T> Optional<T> of(T value) { return new Optional<>(value); } //這個靜態(tài)方法大致是 如果參數(shù)value為空,則創(chuàng)建空對象,如果不為空,則創(chuàng)建有參對象 public static <T> Optional<T> ofNullable(T value) { return value == null ? empty() : of(value); } }
4.2使用場景
場景1:在service層中 查詢一個對象,返回之后判斷是否為空并做處理
Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); Optional.ofNullable(task).orElseThrow(() -> new ProcessException(ErrorCodeEnum,SYSIEM ERROR));
場景2:使用Optional 和函數(shù)式編程,一行搞定
Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); Map<String,String> map = new HashMap<>( initialCapacity: 8); Optional.ofNullable(task).ifPresent(d -> map.put("taskId",d.getTaskDefinitionKey()));
5、總結
每種方法的存在必然有適用的場景,有些情況下這種鏈式編程,雖然代碼優(yōu)雅了。但是,邏輯性沒那么明顯,可讀性有所降低,大家項目中看情況酌情使用。
以上就是一文教你掌握Java如何實現(xiàn)判空的詳細內(nèi)容,更多關于Java判空的資料請關注腳本之家其它相關文章!
相關文章
Mybatis使用on duplicate key update的實現(xiàn)操作
本文主要介紹了Mybatis使用on duplicate key update的實現(xiàn)操作,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-07-07Java?ArrayList實現(xiàn)班級信息管理系統(tǒng)
這篇文章主要為大家詳細介紹了Java?ArrayList實現(xiàn)班級信息管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-02-02springBoot+mybatis-plus實現(xiàn)監(jiān)聽mysql數(shù)據(jù)庫的數(shù)據(jù)增刪改
mybatis-plus技術是簡化了繁瑣的代碼操作,把增刪改查的語句都內(nèi)置了,直接調(diào)用就可以實現(xiàn)數(shù)據(jù)庫的增刪改查了,這篇文章主要給大家介紹了關于springBoot+mybatis-plus實現(xiàn)監(jiān)聽mysql數(shù)據(jù)庫數(shù)據(jù)增刪改的相關資料,需要的朋友可以參考下2024-01-01Spring Boot2配置Swagger2生成API接口文檔詳情
這篇文章主要介紹了Spring Boot2配置Swagger2生成API接口文檔詳情,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-09-09