一文教你掌握J(rèn)ava如何實(shí)現(xiàn)判空
1、前言
實(shí)際項(xiàng)目中我們會(huì)有很多地方需要判空校驗(yàn),如果不做判空校驗(yàn)則可能產(chǎn)生NullPointerException異常。
針對(duì)異常的處理我們?cè)谏弦黄刑峒埃?/p>
先來(lái)看一下實(shí)際項(xiàng)目中一些判空方式

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();
}通常我們判斷一個(gè)對(duì)象是否為Null,可以使用java.util中的Objects.nonNull(obj)、hutool中的ObjectUtil或者直接 null != obj
2、List的判空
像List這種比較特殊的在項(xiàng)目中可能不僅僅是判斷非空了。對(duì)于List來(lái)說(shuō)不等于null和List.size()不等于0是兩回事,公司也有實(shí)習(xí)生常常有把這兩個(gè)混淆的情況,list不等于null說(shuō)明已經(jīng)初始化了,堆內(nèi)存中有一塊屬于它的地盤(pán),而size為0說(shuō)明還沒(méi)往里面放東西,舉個(gè)例子說(shuō)就是不等于null代表我現(xiàn)在有個(gè)瓶子,size大于0說(shuō)明我向瓶子里裝水了。
實(shí)際項(xiàng)目中也發(fā)現(xiàn)有直接用list.isEmpty()去判斷的,來(lái)看一下源碼:
public boolean isEmpty() {
return size == 0;
}相當(dāng)于判斷瓶子里有沒(méi)有水(前提是瓶子已經(jīng)存在,若瓶子不存在,則會(huì)拋出NullPointerException異常)。
所以通常情況下會(huì)連用list != null && list.size > 0 來(lái)判斷,或者直接使用HuTool中CollUtil工具的isEmpty。諸如此類(lèi)的還有Set、Map等
3、String的判空
這里還是用瓶子與水的概念,String為null時(shí)調(diào)用equals(String) 或 length() 等操作拋出 java.lang.NullPointerException。

針對(duì)字符串判空有以下幾種方式:
1、大多數(shù)人使用的方法之一,直觀,方便,但效率低下:
if(a == null || a.equals(""));
2、比較字符串長(zhǎng)度,高效:
if(a == null || a.length() == 0);
3、Java SE 6.0 才剛剛開(kāi)始提供,效率和方法二差不多:
if(a == null || a.isEmpty());
當(dāng)然還可以使用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
該工具類(lèi)中還有個(gè)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)就是用來(lái)防止NullpointException的。常見(jiàn)的方法有:
- .empty():創(chuàng)建一個(gè)空的Optional實(shí)例
- .of(T t) : 創(chuàng)建一個(gè)Optional 實(shí)例,為null時(shí)報(bào)異常
- .ofNullable(T t):若t 不為null,創(chuàng)建Optional 實(shí)例,否則創(chuàng)建空實(shí)例
- isPresent() : 判斷容器中是否有值
- ifPresent(Consume lambda) :容器若不為空則執(zhí)行括號(hào)中的Lambda表達(dá)式
- orElse(T t) : 獲取容器中的元素,若容器為空則返回括號(hào)中的默認(rèn)值
- orElseGet(Supplier s) :如果調(diào)用對(duì)象包含值,返回該值,否則返回s 獲取的值
- orElseThrow() :如果為空,就拋出定義的異常,如果不為空返回當(dāng)前對(duì)象
- map(Function f): 如果有值對(duì)其處理,并返回處理后的Optional,否則返回Optional.empty()
- flatMap(Function mapper):與map 類(lèi)似,要求返回值必須是Optional
- T get() :獲取容器中的元素,若容器為空則拋出NoSuchElement異常
先看個(gè)常見(jiàn)的示例:
baseInfo類(lèi)中有布爾類(lèi)型的屬性,是空返回false,不為空取其值,需要四行。
boolean blind = false;
if (null != baseInfo.getBlind()){
blind = baseInfo.getBlind();
}當(dāng)使用Optional時(shí),一行搞定,非常的優(yōu)雅。
boolean blind = Optional.ofNullable(baseInfo.getBlind()).orElse( other: false);
4.1 Optional對(duì)象的創(chuàng)建
public final class Optional<T> {
private static final Optional<?> EMPTY = new Optional<>();
private final T value;
//可以看到兩個(gè)構(gòu)造方格都是private 私有的
//說(shuō)明 沒(méi)辦法在外面new出來(lái)Optional對(duì)象
private Optional() {
this.value = null;
}
private Optional(T value) {
this.value = Objects.requireNonNull(value);
}
//這個(gè)靜態(tài)方法大致 是創(chuàng)建出一個(gè)包裝值為空的一個(gè)對(duì)象因?yàn)闆](méi)有任何參數(shù)賦值
public static<T> Optional<T> empty() {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY;
return t;
}
//這個(gè)靜態(tài)方法大致 是創(chuàng)建出一個(gè)包裝值非空的一個(gè)對(duì)象 因?yàn)樽隽速x值
public static <T> Optional<T> of(T value) {
return new Optional<>(value);
}
//這個(gè)靜態(tài)方法大致是 如果參數(shù)value為空,則創(chuàng)建空對(duì)象,如果不為空,則創(chuàng)建有參對(duì)象
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
}4.2使用場(chǎng)景
場(chǎng)景1:在service層中 查詢(xún)一個(gè)對(duì)象,返回之后判斷是否為空并做處理
Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); Optional.ofNullable(task).orElseThrow(() -> new ProcessException(ErrorCodeEnum,SYSIEM ERROR));
場(chǎng)景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、總結(jié)
每種方法的存在必然有適用的場(chǎng)景,有些情況下這種鏈?zhǔn)骄幊蹋m然代碼優(yōu)雅了。但是,邏輯性沒(méi)那么明顯,可讀性有所降低,大家項(xiàng)目中看情況酌情使用。
以上就是一文教你掌握J(rèn)ava如何實(shí)現(xiàn)判空的詳細(xì)內(nèi)容,更多關(guān)于Java判空的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
java-servlet-轉(zhuǎn)發(fā)AND路徑(詳解)
下面小編就為大家?guī)?lái)一篇java-servlet-轉(zhuǎn)發(fā)AND路徑(詳解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-10-10
Java實(shí)現(xiàn)圖書(shū)借閱系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)圖書(shū)借閱系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
SpringBoot整合Druid實(shí)現(xiàn)SQL監(jiān)控和數(shù)據(jù)庫(kù)密碼加密
Druid連接池是阿里巴巴開(kāi)源的數(shù)據(jù)庫(kù)連接池項(xiàng)目,Druid連接池為監(jiān)控而生,內(nèi)置強(qiáng)大的監(jiān)控功能,監(jiān)控特性不影響性能,本文給大家介紹了SpringBoot整合Druid實(shí)現(xiàn)SQL監(jiān)控和數(shù)據(jù)庫(kù)密碼加密,文中有相關(guān)的代碼示例供大家參考,需要的朋友可以參考下2024-06-06
JavaSE經(jīng)典小練習(xí)項(xiàng)目之拷貝文件夾
文件拷貝是一個(gè)常見(jiàn)的任務(wù),無(wú)論是備份文件,還是將文件從一個(gè)位置復(fù)制到另一個(gè)位置,文件拷貝都是必不可少的,這篇文章主要給大家介紹了關(guān)于JavaSE經(jīng)典小練習(xí)項(xiàng)目之拷貝文件夾的相關(guān)資料,需要的朋友可以參考下2023-10-10
關(guān)于activemq安裝配置以及啟動(dòng)錯(cuò)誤的解決
這篇文章主要介紹了關(guān)于activemq安裝配置以及啟動(dòng)錯(cuò)誤的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06
Java中用Socket實(shí)現(xiàn)HTTP文件上傳實(shí)例
本篇文章主要介紹了Java中用Socket實(shí)現(xiàn)HTTP文件上傳實(shí)例,詳細(xì)的介紹了通過(guò)讀取Socket的輸入流來(lái)實(shí)現(xiàn)一個(gè)文件上傳的功能,有興趣的同學(xué)可以一起了解一下2017-04-04
Java對(duì)象數(shù)組的添加、刪除和遍歷代碼示例
在Java編程中,我們經(jīng)常需要對(duì)數(shù)據(jù)結(jié)構(gòu)進(jìn)行遍歷操作,并根據(jù)業(yè)務(wù)需求刪除部分元素,這篇文章主要給大家介紹了關(guān)于Java對(duì)象數(shù)組的添加、刪除和遍歷的相關(guān)資料,需要的朋友可以參考下2024-04-04
SpringBoot自動(dòng)初始化數(shù)據(jù)庫(kù)的方法分享
我們?cè)陧?xiàng)目中應(yīng)該經(jīng)常遇到過(guò)初始化數(shù)據(jù)的場(chǎng)景,特別是項(xiàng)目部署或者交付的時(shí)候,那么有什么方式可以在項(xiàng)目啟動(dòng)的時(shí)候自動(dòng)初始化數(shù)據(jù)庫(kù)呢,下面小編就來(lái)和大家分享幾個(gè)方法吧2023-08-08

