Optional使用详解

Optional使用详解

文章目录

  • Optional使用详解
      • 1.构造函数
      • 2.Optional.of(T value)
        • 作用
        • 使用
        • 源码(只想知道怎么用的可以略过)
      • Optional.ofNullable(T value)
        • 作用
        • 使用
        • 源码
      • .orElse(T other)
        • 作用
        • 使用
        • 源码
      • .orElseGet(Supplier other)
        • 作用
        • 使用
        • 源码
      • .map(Function mapper)
        • 作用
        • 使用
        • 源码
      • isPresent()
        • 作用
        • 使用
        • 源码
      • ifPresent(Consumer consumer)
        • 作用
        • 使用
        • 源码
      • filter(Predicate predicate)

为了防止空指针报错NullPointerException,一我们都会加上if,else,想让代码变得更优雅,JAVA8提供了Optional类来优化这种写法

1.构造函数

构造函数使用private修饰,不能直接被外部访问(没办法new出来),Optional的本质,就是内部储存了一个真实的值,在构造的时候,就直接判断其值是否为空。下面为源码


    /**
     * Constructs an instance with the value present.
     *
     * @param value the non-null value to be present
     * @throws NullPointerException if value is null
     */
    private Optional(T value) {
        this.value = Objects.requireNonNull(value);
    }

    //requireNonNull()方法
    public static <T> T requireNonNull(T obj) {
        //使用构造函数创建对象,value为null则报空指针
        if (obj == null)
            throw new NullPointerException();
        return obj;
    }

2.Optional.of(T value)

一般推荐使用Optional.ofNullable(T value),在实际生产中很少使用of()方法,因为使用of()方法,value为null时会报出空指针。不过已有一些场景会用到,比如一些需要空指针暴露的接口或测试类中。

作用

  • 当value值为空时,依然会报NullPointerException
  • 当value值不为空时,能正常构造Optional对象。

使用

//1.当 str=null,报空指针
String str = null;
Optional<String> str1 = Optional.of(str);

源码(只想知道怎么用的可以略过)

   public static <T> Optional<T> of(T value) {
        //构造函数创建对象
        return new Optional<>(value);
    }
   //构造函数
    private Optional(T value) {
        this.value = Objects.requireNonNull(value);
    }
   //requireNonNull()方法
   public static <T> T requireNonNull(T obj) {
       //若传入的value为null,则报空指针
        if (obj == null)
            throw new NullPointerException();
        return obj;
    }


    

Optional.ofNullable(T value)

与of(T value)最大的区别就是,value可以为空,推荐使用

作用

  • 当value值为空时,不会报空指针。
  • 当value值不为空时,能正常构造Optional对象。

使用

String str = null;
//str为空时不会报空指针
Optional<String> str2 = Optional.ofNullable(str);

源码

    public static <T> Optional<T> ofNullable(T value) {
        //value为null时,执行empty()方法
        return value == null ? empty() : of(value);
    }

    public static<T> Optional<T> empty() {
        @SuppressWarnings("unchecked")
        //返回EMPTY对象
        Optional<T> t = (Optional<T>) EMPTY;
        return t;
    }
   // EMPTY对象化就是new Optional<>
    private static final Optional<?> EMPTY = new Optional<>();


.orElse(T other)

作用

如果有值则将其返回,否则返回指定的other对象。

  • 传入的值为null时,执行other并返回
  • 传入的值不为null时,执行other,返回传入的值

使用

执行以下代码,控制台输出Hello被执行了,可见,传入的vaule不为null,但是t.rousHello()依然执行。

    public  String rousHello() {
        System.out.println("Hello被执行了");
        return "Hello!!!";
    }  
   public static void main(String[] args) {
         test1 t=new test1();
     
String s = Optional.ofNullable("Str").orElse(t.rousHello());
     
   }

源码

    public T orElse(T other) {
        //value为ofNullable(T vaule)的value,vaule不为空,返回balue,否则执行other
        return value != null ? value : other;
    }

.orElseGet(Supplier other)

比较推荐使用

作用

  • orElse()一定会被执行,而orElseGet()只有传入的参数为null时才会被执行

  • 只有传入的参数为null情况才才会执行orElseGet()内容

使用

   public  String rousHello() {
        System.out.println("Hello被执行了");
        return "Hello!!!";
    }
String s = Optional.ofNullable(str).orElseGet(() -> t.rousHello());

源码

    public T orElseGet(Supplier<? extends T> other) {
        return value != null ? value : other.get();
    }

.map(Function mapper)

作用

不会返回空指针的获取对象属性

使用


//例如User中有个Address属性,Address对象中有详细地址
public String getCity(User user) throws Exception{
    return Optional.ofNullable(user)
                   .map(u-> u.getAddress())
                   .map(a->a.getCity())
                   .orElseThrow(()->new Exception("获取用户地址失败!"));
}

源码

   public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
       //1.为空则报空指针错误(前面讲过)
        Objects.requireNonNull(mapper);
       //不存在,返回EMPTY对象(前面讲过)
        if (!isPresent())
            return empty();
        else {
            return Optional.ofNullable(mapper.apply(value));
        }
    }

  //requireNonNull()方法
   public static <T> T requireNonNull(T obj) {
       //若传入的value为null,则报空指针
        if (obj == null)
            throw new NullPointerException();
        return obj;
    }

isPresent()

作用

  • 判断是否存在.不存在返回false,存在返回true

使用

boolean present = Optional.ofNullable(user).isPresent();

源码

源码很容易理解,直接判断value是否!=null

    public boolean isPresent() {
        return value != null;
    }

ifPresent(Consumer consumer)

作用

  • 如果存在,则往下走

使用

//如果user存在,则覆盖user的age和name属性       
Optional.ofNullable(user).ifPresent(u->{
            u.setAge(100);
            u.setName("ifPresent");
        });

源码

   public void ifPresent(Consumer<? super T> consumer) {
        if (value != null)
            consumer.accept(value);
    }

filter(Predicate predicate)

作用

  • 如果值存在,并且这个值匹配给定的 predicate,返回一个Optional用以描述这个值,否则返回一个空的Optional。

使用

        user.setName("张四");
        //此处会报空指针,因为get()方法在value为null的情况下会报空指针
        User user1 = Optional.ofNullable(user).filter(
                u -> u.getName() == "张三"
        ).get();

        Optional<User> user2 = Optional.ofNullable(user).filter(
                u -> u.getName() == "张三"
        );
        user2.ifPresent(u->u.setAge(99));

源码

    public Optional<T> filter(Predicate<? super T> predicate) {
        Objects.requireNonNull(predicate);
        if (!isPresent())
            return this;
        else
            return predicate.test(value) ? this : empty();
    }

你可能感兴趣的:(JAVA基础,java)