在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 optional1 = Optional.ofNullable(1);
Optional optional2 = Optional.ofNullable(null);
System.out.println(optional1.isPresent()); // true
System.out.println(optional2.isPresent()); // false
4. 如果值存在,则执行操作
ifPresent(Consumer consumer)方法,可以在Optional对象保存的值不为null时执行指定的操作
Optional optional1 = Optional.ofNullable(1);
Optional 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 optional1 = Optional.ofNullable(1);
Optional optional2 = Optional.ofNullable(null);
System.out.println(optional1.orElse(1000)); // 1
System.out.println(optional2.orElse(1000)); // 1000
6. 异常处理
orElseThrow()方法可以在值不存在时抛出异常,存在时什么都不做,类似于Guava的Precoditions
Optional optional1 = Optional.ofNullable(1);
Optional 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 optional1 = Optional.ofNullable(1);
Optional optional2 = Optional.ofNullable(null);
Optional filter1 = optional1.filter(a -> a == null);
Optional filter2 = optional1.filter(a -> a == 1);
Optional 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 str1Optional = optional1.map(a -> "key" + a);
Optional 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 optional1 = Optional.ofNullable(1);
Optional str1Optional = optional1.map(a -> Optional.of("key" + a));
Optional 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 |
如果值存在,就对该值执行提供的 mapping 函数调用 |
flatMap |
如果值存在,就对该值执行提供的 mapping 函数调用,返回一个 Optional 类型的值,否则就返 回一个空的 Optional 对象 |