記錄Java特性之optional
為什么推出Optional
空指針異常(NullPointerException)空指針異常特別容易在調(diào)用對(duì)象的某個(gè)方法上,我們平常判空時(shí),可能是以下
但是這樣會(huì)顯得特別雜亂無章
所以,optional是可以幫助我們更優(yōu)雅的判空
Optional的概念
本質(zhì)上,這是一個(gè)包含有可選值的包裝類,這意味著 Optional 類既可以含有對(duì)象也可以為空。Optional 是 Java 實(shí)現(xiàn)函數(shù)式編程的強(qiáng)勁一步,并且?guī)椭诜妒街袑?shí)現(xiàn)。但是 Optional 的意義顯然不止于此。
optional的api
判斷是否為空
1.of(T value ) 判斷對(duì)象是否為空 空的話拋出異常,不為空則返回optional包裝的對(duì)象
2.ofNullable(T value) 判斷傳入的值是否為空 不為空返回由Optional封裝的對(duì)象,為空返回 調(diào)用empty()
empty() 會(huì)返回一個(gè)null的Optional包裝類,實(shí)質(zhì)上是null
**
返回默認(rèn)值
1.orElse(T other) Optional對(duì)象不為空,則直接返回對(duì)象,為空,則返回orElse()中的值
2. orElseGet()?—— 其行為略有不同。這個(gè)方法會(huì)在有值的時(shí)候返回值,如果沒有值,它會(huì)執(zhí)行作為參數(shù)傳入的?_Supplier(供應(yīng)者)?_函數(shù)式接口,并將返回其執(zhí)行結(jié)果
兩者的異同
我們接下來看一個(gè)的示例,但這里 Optional ?不為空:
這個(gè)示例中,兩個(gè) Optional ?對(duì)象都包含非空值,兩個(gè)方法都會(huì)返回對(duì)應(yīng)的非空值。不過,orElse() 方法仍然創(chuàng)建了 User 對(duì)象。與之相反,orElseGet() 方法不創(chuàng)建 User 對(duì)象。?結(jié)論:?當(dāng)Optional對(duì)象為空時(shí),orElse(),orElseGet()都會(huì)執(zhí)行括號(hào)中的方法,?當(dāng)Optional對(duì)象不為空時(shí),orElse()會(huì)執(zhí)行括號(hào)中的方法,orElseGet()則不會(huì)執(zhí)行
在執(zhí)行較密集的調(diào)用時(shí),比如調(diào)用 Web 服務(wù)或數(shù)據(jù)查詢,這個(gè)差異會(huì)對(duì)性能產(chǎn)生重大影響。
返回異常
除了 orElse() 和 orElseGet() 方法,Optional 還定義了 orElseThrow() API —— 它會(huì)在對(duì)象為空的時(shí)候拋出異常,而不是返回備選的值:
這個(gè)方法讓我們有更豐富的語義,可以決定拋出什么樣的異常,而不總是拋出 NullPointerException。
轉(zhuǎn)換值
1.map(Function<? super T, ? extends U> mapper)
有很多種方法可以轉(zhuǎn)換 Optional ?的值。我們從** map()** 和?flatMap()?方法開始。先來看一個(gè)使用 map() API 的例子:
map() 對(duì)值應(yīng)用(調(diào)用)作為參數(shù)的函數(shù),然后將返回的值包裝在 Optional 中。這就使對(duì)返回值進(jìn)行鏈?zhǔn)秸{(diào)用的操作成為可能 —— 這里的下一環(huán)就是 orElse()。
2.flatMap(Function<? super T, ? extends Optional<? extends U>> mapper)
相比這下,flatMap() 也需要函數(shù)作為參數(shù),并對(duì)值調(diào)用這個(gè)函數(shù),然后直接返回結(jié)果。下面的操作中,我們給 User 類添加了一個(gè)方法,用來返回 Optional:
既然 getter 方法返回 String 值的 Optional,你可以在對(duì) User 的 Optional 對(duì)象調(diào)用 flatMap() 時(shí),用它作為參數(shù)。其返回的值是解除包裝的 String 值:
過濾值
除了轉(zhuǎn)換值之外,Optional ?類也提供了按條件“過濾”值的方法。?filter() 接受一個(gè) Predicate 參數(shù), 返回測(cè)試結(jié)果為 true ,則返回對(duì)應(yīng)的值。如果測(cè)試結(jié)果為 false,會(huì)返回一個(gè)空的 Optional。
來看一個(gè)根據(jù)基本的電子郵箱驗(yàn)證來決定接受或拒絕 User(用戶) 的示例:
如果通過過濾器測(cè)試,result 對(duì)象會(huì)包含非空值。
總結(jié)
Optional 是 Java 語言的有益補(bǔ)充 —— 它旨在減少代碼中的 NullPointerExceptions,雖然還不能完全消除這些異常。它也是精心設(shè)計(jì),自然融入 Java 8 函數(shù)式支持的功能??偟膩碚f,這個(gè)簡(jiǎn)單而強(qiáng)大的類有助于創(chuàng)建簡(jiǎn)單、可讀性更強(qiáng)、比對(duì)應(yīng)程序錯(cuò)誤更少的程序。