Java8 中引入了一个特别有意思类:Optional,一个可以让我们更加轻松的避免 NPE(空指针异常,NullPointException)的工具。
Optional是java8 util包里类
用来避免使用if(aa == null) {} 这样结构的代码的
1、of、ofNullable
of方法传入的参数不能是null的,否则会抛出NullPointerException
对于可能是null的结果,一定使用ofNullable
2、值为空判断:isPresent、ifPresent
isPresent用来判断值是否为空,类似于obj != null
ifPresent可以传入一个Consumer操作,当值不为空的时候,会执行Consumer函数。
ifPresent这个对象不是null就会执行ifPresent( 里的内容 ) 不会有任何异常
很好用 不用写 !=null
final Optional<List<Student>> value = Optional.ofNullable(nullStudents);
if (value .isPresent()) {
System.out.println("value: " + value .get());
}
上面的方法等价于:
value .ifPresent(u-> System.out.println("value: " + u));
isPresent判断的写法上是不是感觉很熟悉,感觉可以直接写为:
if (nullStudents != null) {
System.out.println("value: " + nullStudents);
}
对于isPresent,如果是在自己可控的代码范围内,完全没有必要将值封装之后再判空。对于自己不可控的代码,后续的filter或者map方法可能比isPresent更好用一些。
3、条件过滤:filter
filter方法提供的是值验证,如果值验证为 true,返回当前值;否则,返回空Optional。
filter 就是相当于一个if的过滤条件
for (final Student s : students) {
Optional.of(s).filter(x -> x.getClazz() == null)
.ifPresent(x -> System.out.println(x.getId()));
}
Person p = new Person();
p.setName("小红");
Optional.ofNullable(p).filter(t->"小明明明".equals(t.getName()))
.ifPresent(t2->System.out.println("filter 里是true的话我才能执行到"));
4、orElse orElseGet
两个作用一样 都是在为null的时候可以给一个默认值
区别是后者是个() -> {} 前者是个对象
Person p = null;
String x = "test";
Person p1 = Optional.ofNullable(p).orElse(new Person());
Person p2 = Optional.ofNullable(p).orElseGet(()->{
System.out.println(x);
return new Person();
});
其他:equals、hashCode、toString
Optional重写了这三个方法。因为Optional可以认为是包装类,
equals方法,Optional.of(s1).equals(Optional.of(s2))完全等价于s1.equals(s2)。
hashCode方法,直接返回的是值的hashCode,如果是空Optional,返回的是0。
toString方法,为了能够识别是Optional,将打印数据包装了一下。如果是空Optional,返回的是字符串“Optional.empty”;如果是非空,返回是是“Optional[值的toString]”。
Optional是一个包装类,且不可变,不可序列化
没有公共构造函数,创建需要使用of、ofNullable方法
空Optional是单例,都是引用Optional.EMPTY
想要获取Optional的值,可以使用get、orElse、orElseGet、orElseThrow