1. 前言

如果你没有处理过空指针,那么你不是一位真正的 Java 程序员。


空指针确实会产生很多问题,我们经常遇到空的引用,然后又想从这个空的引用上去获取其他的值,接着理所当然的碰到了 NullPointException。这是你可能会想,这报错很好处理,然后你看了眼报错行数,对比了下代码。脑海里瞬间闪过 ”对对对,这里有可能为空“,然后加上 null check轻松处理。然而你不知道这已经是你处理的第多少个空指针异常了。

为了解决上面的问题,在 Java SE8 中引入了一个新类 java.util.Optional,这个类可以缓解上面的问题。

你可能已经发现了,上面我用的是缓解而不是解决。这也是很多人理解不太对的地方,以为 Java SE8 中的 Optional 类可以解决空指针问题。其实 Optional 类的的使用只是提示你这里可能存在空值,需要特殊处理,并提供了一些特殊处理的方法。如果你把 Optional 类当作空指针的救命稻草而不加思考的使用,那么依旧会碰到错误。

因为 Optional 是的 Java SE8 中引入的,因此本文中难免会有一些 JDK8 中的语法,如 Lambda 表达式,流处理等,但是都是基本形式,不会有过于复杂的案例。

2. Optional 创建

Optional 的创建一共有三种方式。

/**  * 创建一个 Optional  */ @Test public void createOptionalTest() {     // Optional 构造方式1 - of 传入的值不能为 null     Optional<String> helloOption = Optional.of("hello");      // Optional 构造方式2 - empty 一个空 optional     Optional<String> emptyOptional = Optional.empty();      // Optional 构造方式3 - ofNullable 支持传入 null 值的 optional     Optional<String> nullOptional = Optional.ofNullable(null); }

其中构造方式1中 of 方法,如果传入的值会空,会报出 NullPointerException 异常。

3. Optional 判断

Optional 只是一个包装对象,想要判断里面有没有值可以使用 isPresent方法检查其中是否有值 。

/**  * 检查是否有值  */ @Test public void checkOptionalTest() {     Optional<String> helloOptional = Optional.of("Hello");     System.out.println(helloOptional.isPresent());      Optional<Object> emptyOptional = Optional.empty();     System.out.println(emptyOptional.isPresent()); }

得到的输出:

true false

从 JDK11 开始,提供了 isEmpty方法用来检查相反的结果:是否为空。

如果想要在有值的时候进行一下操作。可以使用 ifPresent方法。

/**  * 如果有值,输出长度  */ @Test public void whenIsPresent() {     // 如果没有值,获取默认值     Optional<String> helloOptional = Optional.of("Hello");     Optional<String> emptyOptional = Optional.empty();     helloOptional.ifPresent(s -> System.out.println(s.length()));     emptyOptional.ifPresent(s -> System.out.println(s.length())); }

输出结果:

5