烦人的空指针异常

编写Java程序的开发者应该对null很熟悉,它表示的是值不存在,如果不对可能为null的对象做一定的校验就直接使用,你会在控制台看到JVM给你打印的NullPointerException异常信息,这会引发程序中断。因此为了解决这个"价值连城的错误",Java提供了一个专门检验对象是否为空的容器类-Optional

如何正确使用Optional

应记住一个核心思想:

Optional是为了在值不存在的情况下产生一个可替代物,如果值存在,那么返回这个值。

我们以实际的案例来分析如果正确使用Optional:

orElse:如果当前的对象为null,匹配默认值
String nullString = null;
// 使用ofNullable创建一个Optional
Optional optionalString = Optional.ofNullable(nullString);
// 如果Optional内的值为null,那么将匹配orElse中的值
String result = optionalString.orElse("");
System.out.println(Objects.equals(result, null));

当然,如果你足够熟悉Optional,直接进行链式调用即可

String result = Optional.ofNullable(nullString).orElse("");

orElseGet:与orElse是一致的,只不过它是一种lambda的形式,你可以将设置默认值的方式封装成一个方法,如果你使用的是领域类,那么可以在这里直接返回初始化类的方法

@SuppressWarnings("all")
public class OptionalDemo {
public static void main(String[] args) {
String nullString = null;
String resultString = Optional.ofNullable(nullString).orElseGet(() -> emptyString());
System.out.println(Objects.equals(result, null));
}
// 这里以String进行举例,实际开发中这个可能是一个对象的初始化工厂方法
public static String emptyString(){
return "";
}
}
orElseThrow: 如果存入Optional的值为null,那么抛出运行时异常
Optional.ofNullable(nullString).orElseThrow(() -> new RuntimeException("这个字符串是空的!"));

控制台打印:

Exception in thread "main" java.lang.RuntimeException: 这个字符串是空的!
at com.xjm.java8.OptionalDemo.lambda$main$1(OptionalDemo.java:28)
at java.util.Optional.orElseThrow(Optional.java:290)
at com.xjm.java8.OptionalDemo.main(OptionalDemo.java:28)
ifPresent:存入Optional中的值不为null的情况下,对传入的Consumer函数进行消费
String existString = "DWG 3:1 SN";
Optional.ofNullable(existString).ifPresent(s -> {
System.out.println("S10总决赛的比分是:"+s);
});

不适合使用Optional的方式

如果只是想判断一个值是否为空,那么没有必要使用Optional,这并不会给你的代码增加任何好处。

// 这是毫无意义的,我更推荐你使用 StringUtils.isNotBalnk()
if (optionalString.isPresent()) {
System.out.println(optionalString.get());
}

使用of对Optional进行构造或者没有处理null的情况下直接使用了get()

// 对null的对象使用了of构造器
Optional errorThing = Optional.of(nullString);
// 没有意义的Optional
String errorMethod = Optional.ofNullable(nullString).get();

查看Optional.get()方法的源码,我们发现,它是自带null的检查的,如果你不处理null的情况下,它将抛出异常中断你的程序执行。

public T get() {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return value;
}

好了,对Optional类的分析就到此为止,对于里面的lambda接口如果有兴趣可以去查阅Java8的函数式编程,本文章不对lambda做拓展。