在Java应用程序中,空指针异常是导致程序失败的最常见原因之一。
为了更加优雅地处理空指针异常,Java8引入了Optional类库。
Optional实际上是一个容器,可以保存类型T的值,或者仅仅保存null。
通过使用Optional,我们能够避免显式进行空值检测,使代码更加清晰和健壮。
1.Optional类是什么?
Optional 类(java.util.Optional) 是一个容器类,它可以保存类型T的值,代表这个值存在。
或者仅仅保存null,表示这个值不存在。原来用 null 表示一个值不存在,现在 Optional 可以更好的表达这个概念,并且可以避免空指针异常。
Optional提供很多有用的方法,这样我们就不用显式进行空值检测。
2. 创建Optional对象
Java8提供了两种方式来创建Optional对象:
- Optional.of():of()不允许参数是null
- Optional.ofNullable():ofNullable()则没有限制
// 参数不能是null
Optional optional1 = Optional.of(1);
// ofNullable参数可以是null
Optional optional2 = Optional.ofNullable(null);
// ofNullable参数也可以不是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. 如果值存在,则执行操作
ifPresent(Consumer consumer)方法,可以在Optional对象保存的值不为null时执行指定的操作
Optional<Integer> optional1 = Optional.ofNullable(1);
Optional<Integer> optional2 = Optional.ofNullable(null);
// 如果不是null,调用Consumer
optional1.ifPresent(value -> System.out.println("value is " + value));
// null,不调用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函数返回值必须是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