天天看點

Guava-Optional可空類型

接上篇guava之joiner和splitter,本篇将介紹guava的另外一個有用的對象optional,這在java中google guava首先給我們提出可空對象模型的。在其他語言如c#這是已經存在很久的模式,并包含在.net類庫中nullable(int?也是一個可空類型)。

回到本文主題optional。在我日常程式設計中nullpointerexception是肯定是大家遇見最多的異常錯誤:

為此doug lea曾說過:

sir c. a. r. hoare也曾說過:

從上面我們能夠足以看出nullpointerexceptiond的出現頻率和可恨之處。是以在gof的設計模式中我們也專門提出了空對象模式(或稱特例模式)來應對這可惡的nullpointerexceptiond。空對象模式主要以傳回一些無意義并不影響處理邏輯的特定對象來替代null對象,進而避免沒必要的null對象的判斷。 例如在計算一組員工的總共薪資的時候,對于傳回的null對象則我們可以傳回預設值為了0薪資的員工對象,那麼我們就不需要做任何null的判斷。

那麼在guava的optional又該怎麼解決呢?在講解optional之前,讓我們仍然以計算一組員工的總共薪資為例用原生java代碼将來看看:

如果換成guava optional将如何:

從上面可以清晰看出,我們不在擔心對象對空了,利用optional的fromnullable建立了一個可空對象,并将其or上一個dummy的員工資訊,是以在這裡我們不在擔心nullpointerexceptiond。

也許你會說和利用三目運算 ( _?:_)沒什麼差别,在此例子中功能是的确是沒多大差距,但是個人覺得guava更有語義,更通用一些,而且滿足很多空對象模式使用的場景。

*. optionalobject.ispresent(): 傳回對象是否有值。

*. optional.absent(): 傳回一個空optional對象,ispresent() 将會傳回false

*. optional.of(): 創optional對象,輸入參數不能為null

*. optional.fromnullable(): 創optional對象,輸入可以為null

*. optionalobject.asset(): 和optional對象值合并,如果為null則傳回size為0的set

*. optionalobject.or(): 和optional對象值合并,如果為null為空加則傳回or參數作為預設值

*. optionalobject.ornull(): 和optional對象值合并,如果為null為空加則傳回null作為預設值

上面的api都是我們在使用optional的時候最常用的方法屬性方法,注意如果我們建立了optional對象,但是沒有判斷ispresent()是否存在,就直接get這是會抛異常的,這屬于亂用optional情況,和直接用null并沒什麼差别。

同樣optional為空對象模式,可以添加預設值,null不會影響我們的處理,如果為null我們無法繼續程式處理的情況,需要抛異常或者中斷的的,還是需要抛異常、中斷,利用preconditions.checknotnull等,而不是繼續套一層optional對象,這也屬于亂用optional之列。