Java8之Optional類


寫在前頭

今天再看阿里的Java開發手冊,里面異常處理第10條提到這樣一個建議。

【推薦】防止 NPE ,是程序員的基本修養,注意 NPE 產生的場景:
1 ) 返回類型為基本數據類型,return 包裝數據類型的對象時,自動拆箱有可能產生 NPE。
反例: public int f() { return Integer 對象}, 如果為 null ,自動解箱拋 NPE 。
2 ) 數據庫的查詢結果可能為 null 。
3 ) 集合里的元素即使 isNotEmpty ,取出的數據元素也可能為 null 。
4 ) 遠程調用返回對象時,一律要求進行空指針判斷,防止 NPE 。
5 ) 對於 Session 中獲取的數據,建議 NPE 檢查,避免空指針。
6 ) 級聯調用 obj . getA() . getB() . getC(); 一連串調用,易產生 NPE 。
正例:使用 JDK8 的 Optional 類來防止 NPE 問題。

里面的正確示例提示我們用Java8的Optional類來防止NPE的問題。

那我們今天就看看這個Optional類吧

 

Optional類

  • 類方法

序號 方法 & 描述
1 static <T> Optional<T> empty()

返回空的 Optional 實例。

2 boolean equals(Object obj)

判斷其他對象是否等於 Optional。

3 Optional<T> filter(Predicate<? super <T> predicate)

如果值存在,並且這個值匹配給定的 predicate,返回一個Optional用以描述這個值,否則返回一個空的Optional。

4 <U> Optional<U> flatMap(Function<? super T,Optional<U>> mapper)

如果值存在,返回基於Optional包含的映射方法的值,否則返回一個空的Optional

5 T get()

如果在這個Optional中包含這個值,返回值,否則拋出異常:NoSuchElementException

6 int hashCode()

返回存在值的哈希碼,如果值不存在 返回 0。

7 void ifPresent(Consumer<? super T> consumer)

如果值存在則使用該值調用 consumer , 否則不做任何事情。

8 boolean isPresent()

如果值存在則方法會返回true,否則返回 false。

9 <U>Optional<U> map(Function<? super T,? extends U> mapper)

如果有值,則對其執行調用映射函數得到返回值。如果返回值不為 null,則創建包含映射返回值的Optional作為map方法返回值,否則返回空Optional。

10 static <T> Optional<T> of(T value)

返回一個指定非null值的Optional。

11 static <T> Optional<T> ofNullable(T value)

如果為非空,返回 Optional 描述的指定值,否則返回空的 Optional。

12 T orElse(T other)

如果存在該值,返回值, 否則返回 other。

13 T orElseGet(Supplier<? extends T> other)

如果存在該值,返回值, 否則觸發 other,並返回 other 調用的結果。

14 <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier)

 

如果存在該值,返回包含的值,否則拋出由 Supplier 繼承的異常

15 String toString()

返回一個Optional的非空字符串,用來調試

 

我們可以看到Optional總共也就10+個方法,其中有三個static方法。並且Optional的構造方法是private,不能new出來。

所以我們一般用這三個static來獲取Optional的對象。

 

  •  of && ofNullable

1 public static <T> Optional<T> of(T value) {
2     return new Optional<>(value);
3 }
4 
5 public static <T> Optional<T> ofNullable(T value) {
6     return value == null ? empty() : of(value);
7 }

很明顯 of 對null對象沒有做任何處理,ofNullable才做了處理。所以當我們不知道傳入的對象是否為null的時候,我們應該選擇用 ofNullable來做處理。

  • map 

1 public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
2     Objects.requireNonNull(mapper);
3     if (!isPresent())
4         return empty();
5     else {
6         return Optional.ofNullable(mapper.apply(value));
7     }
8 }

如果我們想獲取Object里面的值的話,我們就需要用到這個map。

 

例子

 1 public class OptionalTest {
 2     public static void main(String[] args) {
 3         Person person = new Person("zhangsan", 18);
 4         String name = getName(person);
 5         System.out.println(name);
 6     }
 7 
 8     private static String getName(Person person) {
 9         if (Objects.isNull(person)) {
10             return "unKnown";
11         }
12         return person.getName();
13     }
14 
15 }

我們看上面的這個例子。

我們有一個函數 getName 作用是獲取Person對象的名字。但我並不知道這個Person是否為Null。

所以我要進行一個判斷,判斷Person是否為空,在做決定。

但如果我們使用Optional類的話,我們可以這樣寫

 1 public class OptionalTest {
 2     public static void main(String[] args) {
 3         Person person = new Person("zhangsan", 18);
 4         String name = getName(person);
 5         System.out.println(name);
 6     }
 7 
 8     private static String getName(Person person) {
 9         String name = Optional.ofNullable(person).map(x -> x.getName())
10                 .orElse("unKnown");
11         return name;
12     }
13 }

如果傳入的為空,它會自動new一個  Optional<T> t = (Optional<T>) EMPTY; 

有效的處理到了null的問題,而且還非常的簡潔。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM