Optional类的使用

【JAVA8新特性】Optional

这是实习中学到新的类,看业务代码时发现大佬们喜欢用这个类,特别钻研了一下。

  • Optional是一个可以为null的容器对象:它可以保存类型T的值,或者仅仅保存null。
  • 如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。
  • Optional提供很多有用的方法,这样我们就不用显式进行空值检测。
  • Optional 类的引入很好的解决空指针异常。

源码分析:

1. 类的结构和构造器
public final class Optional<T> {
    
    // 这个常量为后面调用 empty() 方法时实例化一个Optional对象做准备
    private static final Optional<?> EMPTY = new Optional<>();

    // 容器内部的值
    private final T value;

    private Optional() {
        this.value = null;
    }

	private Optional(T value) {
        this.value = Objects.requireNonNull(value);
    }
    // ...
}
2. empty() 方法

该静态方法的泛型T都是由调用该方法的Optional的泛型类型决定,empty()方法其实很简单,将该类的常量EMPTY强制转换为相同类型的Optional对象,而这个empty()方法返回的Optional对象的value值为null

    public static<T> Optional<T> empty() {
        @SuppressWarnings("unchecked")
        Optional<T> t = (Optional<T>) EMPTY;
        return t;
    }

测试一下:

	public static void main(String[] args){
        Optional<Integer> optional = Optional.empty();
        Integer i = optional.get();
        System.out.println(i);
    }

此时会抛异常:java.util.NoSuchElementException: No value present。
原因在于,Optional.empty()后创建的optional的value为null,get()方法的时候会判断value是否为null,如果时null就报错。可以看下一条get()方法的源码。

3. get() / isEmpty() / isPresent() 方法

比较简单,放在一起了。

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

	public boolean isEmpty() {
        return value == null;
    }

	public boolean isPresent() {
        return value != null;
    }
4. of(T value) / ofNullable(T value) 方法

通过看最开始的源码,可以发现,Optional类将自己的两个构造方法全部私有化,那么肯定会开放公共方法供外部访问。

	public static <T> Optional<T> of(T value) {
        return new Optional<>(value);
    }

	public static <T> Optional<T> ofNullable(T value) {
        return value == null ? empty() : of(value);
    }

看出区别:ofNullable(T value)创造l时value可以是null,of(T value)的value不能为null
可以看到new Optional<>(value)的构造函数为:

	private Optional(T value) {
        this.value = Objects.requireNonNull(value);
    }

继续看Objects.requireNonNull(value)的源码:

	public static <T> T requireNonNull(T obj) {
        if (obj == null)
            throw new NullPointerException();
        return obj;
    }

null时直接抛异常了。

5. ifPresent() / ifPresentOrElse() 方法

简答地说,Consumer类包含一个 accept 抽象方法。该抽象方法对传入的值进行处理,但没有返回值。

  • ifPresent():如果value存在就做处理,否则就不处理。
  • ifPresentOrElse() 方法:如果value存在就做处理,否则用emptyAction处理。
    public void ifPresent(Consumer<? super T> action) {
        if (value != null) {
            action.accept(value);
        }
    }
    
    public void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction) {
        if (value != null) {
            action.accept(value);
        } else {
            emptyAction.run();
        }
    }
6. or() / orElse() / orElseGet() / orElseThrow() 方法

这个方法是用来取值的。

    public Optional<T> or(Supplier<? extends Optional<? extends T>> supplier) {
        Objects.requireNonNull(supplier);
        if (isPresent()) {
            return this;
        } else {
            @SuppressWarnings("unchecked")
            Optional<T> r = (Optional<T>) supplier.get();
            return Objects.requireNonNull(r);
        }
    }
    
	public T orElse(T other) {
        return value != null ? value : other;
    }
    
    public T orElseGet(Supplier<? extends T> supplier) {
        return value != null ? value : supplier.get();
    }

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

	public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
        if (value != null) {
            return value;
        } else {
            throw exceptionSupplier.get();
        }
    }
7. filter() 方法

过滤是否符合要求的值。如果value存在,进行过滤。

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

如果value存在就返回一个仅包含一个value值的stream。

	public Stream<T> stream() {
        if (!isPresent()) {
            return Stream.empty();
        } else {
            return Stream.of(value);
        }
    }

看完源码基本就知道如何使用了。之后再更吧。。

参考链接:https://www.jianshu.com/p/dfdc3a0dacca

发布了33 篇原创文章 · 获赞 9 · 访问量 8695

猜你喜欢

转载自blog.csdn.net/Serena0814/article/details/97128601