Java8判空新寫法

一、前言

? ? 空指針真的是我們開發(fā)中經(jīng)常會(huì)碰到的問題,例如一個(gè)類

public class User() {
? ? private String userName;
? ? private String password;
? ? private List<User> children;
}

? ? 代碼中如下調(diào)用:user.getChildren().getUserName()
? ? 當(dāng)user為空的時(shí)候,這句代碼就有可能會(huì)報(bào)NullPointerException。為了解決這類問題呢,我們通常就會(huì)做很多的判空操作

if(user!=null) {
?????User smallUser = user.getChildren();
?????if(smallUser!=null){
?????????String smallName = smallUser.getUserName();
?????}
}

? ? 這種方式是最不優(yōu)雅的,為了避免這類問題,Java8提供了Optional類來優(yōu)化這種寫法。Optional不是對null關(guān)鍵字的一種替代,而是對于null判定提供了一種更加優(yōu)雅的實(shí)現(xiàn)。

二、API介紹

? ??1、of(T value),ofNullable(T value)
? ??????Optional的本質(zhì),就是內(nèi)部儲(chǔ)存了一個(gè)真實(shí)的值,在構(gòu)造的時(shí)候,就直接判斷其值是否為空

Optional(T value)構(gòu)造函數(shù)的源碼

? ? 1.1??of(T value)的源碼如下

public static <T> Optional<T> of(T value) {
?????return new Optional<>(value);
}

? ? 在of(T value)的實(shí)現(xiàn)源碼里也是調(diào)用了后遭方法,在這里可以看出,如果value值是空的,那么這里依舊會(huì)出現(xiàn)空指針異常的情況。
? ? 1.2??ofNullable(T value)?的源碼如下

public static <T> Optional<T> ofNullable(T value) {
?????return value == null ? empty() : of(value);
}

? ? 跟of(T value) 相比區(qū)別就是,如果value是null,of(T value)會(huì)報(bào)空指針異常,但是ofNullable(T value)不會(huì)拋出異常,而是直接返回一個(gè)EMPTY對象。這不是意味著of(T value) 一點(diǎn)用處都沒有的,如果我們的項(xiàng)目中并不想隱藏空指針異常,而是需要檢測到改情況并作特殊處理等情況的話就需要使用of(T value) 這個(gè)方法了。

? ??2、orElse(T other),orElseGet(Supplier<? extends T> other)和orElseThrow(Supplier<? extends X> exceptionSupplier)
? ? ? ? 這三個(gè)方法是在構(gòu)造函數(shù)傳入的value為null的時(shí)候進(jìn)行調(diào)用的。

user = Optional.ofNullable(user).orElse(createUser());
?user = Optional.ofNullable(user).orElseGet(() -> createUser());
Optional.ofNullable(user).orElseThrow(()->new Exception("不認(rèn)識(shí)"));

? ???當(dāng)user值不為null時(shí),orElse函數(shù)依然會(huì)執(zhí)行createUser()方法,而orElseGet函數(shù)并不會(huì)執(zhí)行createUser()方法。
? ? orElseThrow,就是value值為null時(shí),直接拋一個(gè)異常出去

3、map(Function<? super T, ? extends U> mapper)和flatMap(Function<? super T, Optional<U>> mapper)

public final class Optional<T> {
?????public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
?????????Objects.requireNonNull(mapper);
?????????if (!isPresent())
?????????????return empty();
?????????else {
?????????????return Optional.ofNullable(mapper.apply(value));
?????????}
?????}

?????public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
?????????Objects.requireNonNull(mapper);
?????????if (!isPresent())
?????????????return empty();
?????????else {
?????????????return Objects.requireNonNull(mapper.apply(value));
?????????}
?????}?
}

? ? 這兩個(gè)函數(shù)主要的區(qū)別就是入?yún)?,map函數(shù)所接受的入?yún)㈩愋蜑镕unction<? super T, ? extends U>,而flapMap的入?yún)㈩愋蜑镕unction<? super T, Optional<U>>。

4、isPresent()和ifPresent(Consumer<? super T> consumer)

????isPresent()即判斷value值是否為空,而ifPresent就是在value值不為空時(shí),做一些操作。這兩個(gè)函數(shù)是目前我在代碼中判空使用較多的??梢宰尨a更優(yōu)雅一些。

public final class Optional<T> {
???? public boolean isPresent() {
?????????return value != null;
?????}?
?????public void ifPresent(Consumer<? super T> consumer) {
?????????if (value != null)
?????????????consumer.accept(value);
?????}
}

5、filter(Predicate<? super T> predicate)

public final class Optional<T> {
? ? Objects.requireNonNull(predicate);
?????if (!isPresent())
?????????return this;
?????else
?????????return predicate.test(value) ? this : empty();?
}

? ? filter方法通過接收一下predicate來對Optional中包含的值進(jìn)行過濾,如果包含的值滿足條件,那么還是原樣返回,否則返回empty。
? ? 用法:
? ??????Optional<User> user1 = Optional.ofNullable(user).filter(u -> u.getAge()<=20);
? ? ? ? 如果user的age年齡小于等于20的,則返回。如果是大于20的,則返回一個(gè)EMPTY對象。

巧妙的運(yùn)用Optional會(huì)提高代碼效率,使代碼變得更加優(yōu)雅。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容