概述
我们在编写代码的时候出现最多的就是空指针异常。所以在很多情况下我们需要做各种非空的判断。
模拟一个空指针异常:
public class OptionalDemo {
public static void main(String[] args) {
Author author = getAuthor();
System.out.println(author.getName());
}
public static Author getAuthor() {
Author author = new Author(1L, "蒙多", 33, "一个从菜刀中明悟哲理的祖安人", null);
return null;
}
}
之前的解决办法:进行非空判断
public class OptionalDemo {
public static void main(String[] args) {
Author author = getAuthor();
if (author != null) {
System.out.println(author.getName());
}
}
public static Author getAuthor() {
Author author = new Author(1L, "蒙多", 33, "一个从菜刀中明悟哲理的祖安人", null);
return null;
}
}
使用
创建对象
Optional就好像是包装类,可以把我们的具体数据封装Optional对象内部。然后我们去使用Optional中封装好的方法操作封装进去的数据就可以非常优雅的避免空指针异常。
我们一般使用Optional的静态方法ofNullable来把数据封装成一个Optional对象。无论传入的参数是否为null都不会出现问题。
public class OptionalDemo {
public static void main(String[] args) {
Author author = getAuthor();
//把数据封装成一个Optional对象
Optional<Author> author1 = Optional.ofNullable(author);
//使用ifPresent方法消费
author1.ifPresent(new Consumer<Author>() {
@Override
public void accept(Author author) {
System.out.println(author.getName());
}
});
}
public static Author getAuthor() {
Author author = new Author(1L, "蒙多", 33, "一个从菜刀中明悟哲理的祖安人", null);
return author;
}
}
你可能会觉得还要加一行代码来封装数据比较麻烦。但是如果改造下getAuthor方法,让其的返回值就是封装好的Optional的话,我们在使用时就会方便很多。
public class OptionalDemo {
public static void main(String[] args) {
Optional<Author> authorOptional = getAuthorOptional();
authorOptional.ifPresent(new Consumer<Author>() {
@Override
public void accept(Author author) {
System.out.println(author.getName());
}
});
}
//改造getAuthor方法
public static Optional<Author> getAuthorOptional() {
Author author = new Author(1L, "蒙多", 33, "一个从菜刀中明悟哲理的祖安人", null);
return Optional.ofNullable(author);
}
}
安全消费值
我们获取到一个Optional对象后肯定需要对其中的数据进行使用。这时候我们可以使用其ifPresent方法对来消费其中的值。
这个方法会判断其内封装的数据是否为空,不为空时才会执行具体的消费代码。这样使用起来就更加安全了。
获取值
如果我们想获取值自己进行处理可以使用get方法获取,但是不推荐。因为当Optional内部的数据为空的时候会出现异常。
orElseGet
获取数据并且设置数据为空时的默认值。如果数据不为空就能获取到该数据。如果为空则根据你传入的参数来创建对象作为默认值返回。
orElseThrow
获取数据,如果数据不为空就能获取到该数据。如果为空则根据你传入的参数来创建异常抛出。在Spring中可以使用统一异常处理。
过滤
我们可以使用filter方法对数据进行过滤。如果原本是有数据的,但是不符合判断,也会变成一个无数据的Optional对象。
判断
之前用的是 ifPresent 注意区分
我们可以使用isPresent方法进行是否存在数据的判断。如果为空返回值为false,如果不为空,返回值为true。但是这种方式并不能体现Optional的好处,更推荐使用ifPresent方法。
if (authorOptional.isPresent()) {
System.out.println(authorOptional.get().getName());
System.out.println(authorOptional.get().getAge());
}
数据转换
Optional还提供了map可以让我们的对数据进行转换,并且转换得到的数据也还是被Optional包装好的,保证了我们的使用安全。
例如我们想获取作家的书籍集合。