來源:juejin.cn/post/7224027867084292154
1 前言
2 List的判空
3 String的判空
4 Optional
4.1 Optional物件的建立
4.2 使用場景
5 總結
1 前言
實際計畫中我們會有很多地方需要判空校驗,如果不做判空校驗則可能產生
NullPointerException
異常。
針對異常的處理我們在上一篇有提及:
先來看一下實際計畫中一些判空方式
通常我們判斷一個物件是否為Null,可以使用
java.util
中的
Objects.nonNull(obj)
、hutool中的ObjectUtil或者直接 null != obj
2 List的判空
像List這種比較特殊的在計畫中可能不僅僅是判斷非空了。對於List來說不等於null和
List.size()
不等於0是兩回事,公司也有實習生常常有把這兩個混淆的情況,list不等於null說明已經初始化了,堆記憶體中有一塊屬於它的地盤,而size為0說明還沒往裏面放東西,舉個例子說就是不等於null代表我現在有個瓶子,size大於0說明我向瓶子裏裝水了。
實際計畫中也發現有直接用
list.isEmpty()
去判斷的,來看一下源碼:
相當於判斷瓶子裏有沒有水(前提是瓶子已經存在,若瓶子不存在,則會丟擲
NullPointerException
異常)。
所以通常情況下會連用
list != null && list.size > 0
來判斷,或者直接使用HuTool中CollUtil工具的isEmpty。諸如此類的還有Set、Map等
3 String的判空
這裏還是用瓶子與水的概念,String為null時呼叫
equals(String)
或
length()
等操作丟擲
java.lang.NullPointerException
。
針對字串判空有以下幾種方式:
1、大多數人使用的方法之一,直觀,方便,但效率低下:
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的出現就是用來防止
NullpointException
的。常見的方法有:
.empty()
:
建立一個空的Optional例項
.of(T t)
:
建立一個Optional 例項,為null時報異常
.ofNullable(T t)
:
若t 不為null,建立Optional 例項,否則建立空例項
isPresent()
:
判斷容器中是否有值
ifPresent(Consume lambda)
:
容器若不為空則執行括弧中的Lambda運算式
orElse(T t)
:
獲取容器中的元素,若容器為空則返回括弧中的預設值
orElseGet(Supplier s)
:
如果呼叫物件包含值,返回該值,否則返回s 獲取的值
orElseThrow()
:
如果為空,就丟擲定義的異常,如果不為空返回當前物件
map(Function f)
:
如果有值對其處理,並返回處理後的Optional,否則返回
Optional.empty()
flatMap(Function mapper)
:
與map 類似,要求返回值必須是Optional
T get()
:
獲取容器中的元素,若容器為空則丟擲
NoSuchElement
異常
先看個常見的範例:
baseInfo類中有布爾型別的內容,是空返回false,不為空取其值,需要四行。
當使用Optional時,一行搞定,非常的優雅。
4.1 Optional物件的建立
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);
}
//這個靜態方法大致 是建立出一個包裝值為空的一個物件因為沒有任何參數賦值
public static<T> Optional<T> empty() {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY;
return t;
}
//這個靜態方法大致 是建立出一個包裝值非空的一個物件 因為做了賦值
public static <T> Optional<T> of(T value) {
return new Optional<>(value);
}
//這個靜態方法大致是 如果參數value為空,則建立空物件,如果不為空,則建立有參物件
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
}
4.2 使用場景
場景1:在service層中 查詢一個物件,返回之後判斷是否為空並做處理
場景2:使用Optional 和函數語言程式設計,一行搞定
5 總結
每種方法的存在必然有適用的場景,有些情況下這種鏈式編程,雖然程式碼優雅了。但是,邏輯性沒那麽明顯,可讀性有所降低,大家計畫中看情況酌情使用。
>>
END
精品資料,超贊福利,免費領
微信掃碼/長按辨識 添加【技術交流群】
群內每天分享精品學習資料
最近開發整理了一個用於速刷面試題的小程式;其中收錄了上千道常見面試題及答案(包含基礎、並行、JVM、MySQL、Redis、Spring、SpringMVC、SpringBoot、SpringCloud、訊息佇列等多個型別),歡迎您的使用。
👇👇
👇點選"閱讀原文",獲取更多資料(持續更新中)