Optional 使用方式

从java 8开始引入了Optional类,Optional 的出现是为了解决 NPE(NullPointerException)异常,那是怎么用呢?
在没有出现这个类之前要访问一个对象时

user.getAddress().getId()

你要先有一个很冗长的判断

 if (user != null) {
     if (user.getAddress() != null) {
                
     }
 }

Optional 是怎么做呢?

  1. 创建Optional对象
  Optional user1 = Optional.empty();

这样呢,也是创建了一个空的对象,在调用user1.get()的时,也是会报错 NoSuchElementException
我们可以调用 ofofNullable两个方法
of 方法是要求传入的对象不能为空

Optional a = Optional.of(user);

ofNullable 传入的对象,可以为空,也可以不空

Optional a = Optional.ofNullable(user);
  1. 访问 Optional对象
    当我们利用 ofofNullable 创建好对象之后,即可利用 get() 方法取获取对象了
  Optional user1 = Optional.ofNullable(user);
  user1.get();

再看他的源码,仍然有可能会报错

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

那我们可以先调用 ifPresent()方法 ,可以先验证当前值是否为null

 Optional user1 = Optional.ofNullable(user);
 if(user1.isPresent()) {
       user1.get();
  }

同样还有另一个方法也可以处理,ifPresent(),该方法通过传入一个Consumer,如果不为空,就会执行传入的Lambda 表达式

Optional user1 = Optional.ofNullable(user);
user1.ifPresent( x-> {
     System.out.println(x.getId());
 });

3.返回默认值
Optional 的 API 提供了返回对象值,或是在为空的情况下返回默认值
orElseorElseGet 方法分别提供了两个选择

  1. orElse
    @Test
    public void testOrElse() {
        User a = null;
        User b = new User("b", "bname");
        User result = Optional.ofNullable(a).orElse(b);
        Assert.assertEquals("b", result.getId());
    }

上面的结果会返回 b对象

  1. orElseGet
  @Test
    public void testOrElseGet() {
        User a = null;
        User b = new User("b", "bname");
        User result = Optional.ofNullable(a).orElseGet(() -> b);
        Assert.assertEquals("b", result.getId());
    }

同样是返回b的对象
这是在a都为空的情况下,执行的结果是一样的
那如果a不为空的情况下呢?
我们先来重构下,把创建 b对象的提取出来,同时增加日志

    public User createUser() {
        System.out.println("logging  create user b");
        return new User("b", "bname");
    }

来测试下orElse

    @Test
    public void testOrElse() {
        User a = new User("a", "aname");
        User result = Optional.ofNullable(a).orElse(createUser());
        Assert.assertEquals("a", result.getId());
    }

看输出结果,也是会执行createUser()

image.png

再来看下 orElseGet

@Test
    public void testOrElseGet() {
        User a = new User("a", "aname");
        User result = Optional.ofNullable(a).orElseGet(() -> createUser());
        Assert.assertEquals("a", result.getId());
    }

输出结果,并不会输出create user b 的日志

image.png

其实也很好理解的,因为orElse 方法是一定要先创建好对象作为参数的,而orElseGet 是通过lambda 函数传入,只有为空的情况下,才会调用这个方法,所以在调用这些方法的时候,要很注意,由其是有操作网络连接相关的操作时,要按实际情况来决定使用哪个方法作为默认值的提供方

你可能感兴趣的:(Optional 使用方式)