美文网首页SpringFramework
Optional 使用方式

Optional 使用方式

作者: David_jim | 来源:发表于2019-08-04 11:45 被阅读4次

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

    user.getAddress().getId()
    

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

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

    Optional 是怎么做呢?

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

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

    Optional<User> a = Optional.of(user);
    

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

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

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

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

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

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

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

    Optional<User> 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 使用方式

        本文链接:https://www.haomeiwen.com/subject/mmbedctx.html