Optional類的使用指南:解決空指針異常
在Java應用程序中,空指針異常是導致程序失敗的最常見原因之一。為了更加優(yōu)雅地處理空指針異常,Java8引入了Optional類庫。Optional實際上是一個容器,可以保存類型T的值,或者僅僅保存null。通過使用Optional,我們能夠避免顯式進行空值檢測,使代碼更加清晰和健壯。
1.Optional類是什么?
Optional 類(java.util.Optional) 是一個容器類,它可以保存類型T的值,代表這個值存在?;蛘邇H僅保存null,表示這個值不存在。原來用 null 表示一個值不存在,現(xiàn)在 Optional 可以更好的表達這個概念。并且可以避免空指針異常。
Optional提供很多有用的方法,這樣我們就不用顯式進行空值檢測。
2. 創(chuàng)建Optional對象
Java8提供了兩種方式來創(chuàng)建Optional對象:
- Optional.of():of()不允許參數(shù)是null
- Optional.ofNullable():ofNullable()則沒有限制
// 參數(shù)不能是null
Optional optional1 = Optional.of(1);
// ofNullable參數(shù)可以是null
Optional optional2 = Optional.ofNullable(null);
// ofNullable參數(shù)也可以不是null
Optional optional3 = Optional.ofNullable(2);
3. 判斷值是否存在
使用isPresent()方法可以判斷Optional對象中的值是否存在。
Optional<Integer> optional1 = Optional.ofNullable(1);
Optional<Integer> optional2 = Optional.ofNullable(null);
System.out.println(optional1.isPresent()); // true
System.out.println(optional2.isPresent()); // false
4. 如果值存在,則執(zhí)行操作
ifPresent(Consumer consumer)方法,可以在Optional對象保存的值不為null時執(zhí)行指定的操作
Optional<Integer> optional1 = Optional.ofNullable(1);
Optional<Integer> optional2 = Optional.ofNullable(null);
// 如果不是null,調(diào)用Consumer
optional1.ifPresent(value -> System.out.println("value is " + value));
// null,不調(diào)用Consumer
optional2.ifPresent(value -> System.out.println("value is " + value));
輸出結果:
value is 1
5. 獲取值或默認值
orElse(value)方法,可以在Optional對象保存的值不為null時返回原來的值,否則返回指定的默認值
Optional<Integer> optional1 = Optional.ofNullable(1);
Optional<Integer> optional2 = Optional.ofNullable(null);
System.out.println(optional1.orElse(1000)); // 1
System.out.println(optional2.orElse(1000)); // 1000
6. 異常處理
orElseThrow()方法可以在值不存在時拋出異常,存在時什么都不做,類似于Guava的Precoditions
Optional<Integer> optional1 = Optional.ofNullable(1);
Optional<Integer> optional2 = Optional.ofNullable(null);
optional1.orElseThrow(() -> new IllegalStateException());
try {
optional2.orElseThrow(() -> new IllegalStateException());
} catch (IllegalStateException e) {
e.printStackTrace();
}
7. 過濾和映射操作
Optional類還提供了filter(Predicate)和map(Function)方法,用于對Optional對象中保存的值進行過濾和映射
Optional<Integer> optional1 = Optional.ofNullable(1);
Optional<Integer> optional2 = Optional.ofNullable(null);
Optional<Integer> filter1 = optional1.filter(a -> a == null);
Optional<Integer> filter2 = optional1.filter(a -> a == 1);
Optional<Integer> filter3 = optional2.filter(a -> a == null);
System.out.println(filter1.isPresent()); // false
System.out.println(filter2.isPresent()); // true
System.out.println(filter2.get().intValue() == 1); // true
System.out.println(filter3.isPresent()); // false
Optional<String> str1Optional = optional1.map(a -> "key" + a);
Optional<String> str2Optional = optional2.map(a -> "key" + a);
System.out.println(str1Optional.get()); // key1
System.out.println(str2Optional.isPresent()); // false
8. flatMap操作
flatMap()方法與map()相似,不同之處在于flatMap()的mapping函數(shù)返回值必須是Optional類型
Optional<Integer> optional1 = Optional.ofNullable(1);
Optional<Optional<String>> str1Optional = optional1.map(a -> Optional.of("key" + a));
Optional<String> str2Optional = optional1.flatMap(a -> Optional.of("key" + a));
System.out.println(str1Optional.get().get()); // key1
System.out.println(str2Optional.get()); // key1
9. Optional類的方法總結
方法 | 描述 |
empty | 返回一個空的 Optional 實例 |
of | 將指定值用 Optional 封裝之后返回,如果該值為 null,則拋出一個 NullPointerException 異常 |
ofNullable | 將指定值用 Optional 封裝之后返回,如果該值為 null,則返回一個空的 Optional 對象 |
orElse | 如果有值則將其返回,否則返回一個默認值 |
orElseThrow | 如果有值則將其返回,否則拋出一個由指定的 Supplier 接口生成的異常 |
filter | 如果值存在并且滿足提供的斷言, 就返回包含該值的 Optional 對象;否則返回一個空的 Optional 對象 |
map | 如果值存在,就對該值執(zhí)行提供的 mapping 函數(shù)調(diào)用 |
flatMap | 如果值存在,就對該值執(zhí)行提供的 mapping 函數(shù)調(diào)用,返回一個 Optional 類型的值,否則就返 回一個空的 Optional 對象 |