zoukankan      html  css  js  c++  java
  • java8的Optional

    前言

      java中的null是每位java开发者无法回避的问题,也是无比痛恨的问题。逻辑上明明正常的程序,在运行的时候却偏偏会抛出NullPointException。在做所有的操作之前(set/get/equals等),都必须加上一行"if(xxx != null)"来进行判断,否则有很大概率会在运行时看到一堆NullPointException。另外有些工作经验的程序员都知道,就算本人心里很放心对象不会为null,也必须判断,否则代码上线前的sonar检查一般都是通不过的。

    Optional的使用

    ​   java的创建者在后来也发现了这个问题,对于null,创建者们现在的普遍观点也是认为这是一个失误。所以在java8中对此做出了相应的补救措施,这个补救就是Optional类。

    ​   通过将对象(空对象/非空对象)放入Optional类中,然后通过Optional提供的API来获取和操作该类,帮助优雅的对null进行相应的处理。而不是在代码中写一大堆类似"if(xxx != null)"的代码。

    ​   我们应该将需要操作的对象先放入Optional对象中,再进行相应的操作,这就要求我们首先得构建出Optional对象。查看Optional的源码可以发现,该类的所有构造方法均被private修饰,所以需要通过Optional类提供的一些静态方法来构建。常用的静态方法有如下三个:

    Optional optional = Optional.of(object); // 如果object==null,会抛出NullPointerException
    Optional optional = Optional.ofNullable(object); // 如果object==null,底层调用Optional.Empty()方法创建Optional对象
    Optional optional = Optional.empty(); // 返回一个value==null的Optional对象

      通过上述三个方法中的任意一个,都可以得到一个Optional对象,其中常用的是前两个。

    ​   对于Optional的对象,一般还有两个常用的API,分别是:

    boolean isNull = optional.isPresent(); //判断optional中的对象是否为非null对象
    Object object = optional.get(); // 从optional中取出放置的对象。如果放置的值为null,那么会抛出NoSuchElementException异常

      下面开始举一个实际的小案例来说明应该如何使用Optional。假设我们有一个student的对象,现在需要调用其getName()方法

    Student student = ....; // 通过某种方式(new/db/method等)获得,所以可能为null
    // 不使用Optional的方式
    if(student != null) { 
        student.getName(); 
    }
    // 使用Optional的方式
    Optional<Student> optional = Optional.ofNullable(student); // 不能使用Optional.of(),因为不确实student是否为null
    if(optional.isPresent()) {
        Student stu = optional.get(); // optional.isPresent()为true,说明其中存放的对象不会为null
        stu.getName();
    }

      上述代码完美的实现了功能,避免的NullPotionException。但是明显能看到,对于null的判断反而复杂化了,而且从代码的阅读角度来说,这样的代码多了之后,明显对代码的阅读也会带来不小的负担。毕竟java中"get()"这样的方法挺多的(像ThreadLocal等)。

    ​   所以Optional的使用的正确打开方式明显不是这样的。对比java8中另一大特性Stream来看,我们会发现,java8中特别推崇的一种编码风格就是流式编程。Optional不外如是。

    ​   下面我们尝试通过流失编程的方式,美化下上述代码。

    ​   这里引入一个新的API——isElse(object)。一般搭配Optional.ofNullable(object)使用。如果Optional.ofNullable(object)中的object==null,那么就会走isElse作为保底,保证Optional对象中存放的对象一定不为null。所以就可以写出如下代码:

    // 流式编程。  orElse返回值是T(Optional<T>)
    Optional.ofNullable(student).orElse(new Student()).getName();

      orElse系列方法其实有三个,一般都是配合Optional.ofNullable(object)使用,分别如下:

    orElse(T other); // 保底,如果Optional.ofNullable(object)中的object==null,那就返回传入的other
    orElseGet(Supplier<? extends T> other); // 保底,如果如果Optional.ofNullable(object)中的object==null,返回传入lambda表达式返回的值
    orElseThrow(Supplier<? extends X> exceptionSupplier); // 保底,如果Optional.ofNullable(object)中的object==null,返回传入lambda表达式抛出的异常

      更多的时候,Optional配合Stream可以写出非常简洁的流式编程的代码,代码如下:

    public class Test {
        
        public static void main(String[] args) {
            Student student = new Student();
            List<String> collect = Optional.ofNullable(student.getCourses())
                                           .orElse(new ArrayList<>())
                                           .stream().map(s -> s)
                                           .collect(Collectors.toList()); 
        }
        @Data
        static class Student {
            List<String> courses ;
        }
    }
  • 相关阅读:
    .NetMVC过滤器
    Vue-cli配置
    回顾2019年到今天
    八皇后问题
    约瑟夫环问题
    斐波那契函数列
    提高学习效率的方法
    感受爱阅读笔记
    Android IO流汇总
    Android的AsyncTask
  • 原文地址:https://www.cnblogs.com/Bingfengwangzuo/p/13886198.html
Copyright © 2011-2022 走看看