Java Optional orElse,orElseGet,orElseThrow()用法及代码示例

Java Optional orElse,orElseGet,orElseThrow()用法及代码示例

我们都知道,Optional类是Java8为了解决null值判断问题,使用Optional类可以避免显式的判断null值(null的防御性检查),避免null导致的NPE(NullPointerException) 。

在介绍这三个方法之前,先讲讲 Optional 的 ofNullable() 方法,因为他们常常搭配一起使用。

我们来看看 ofNullable() 方法的源码:

/**
 * A container object which may or may not contain a non-null value.
 * If a value is present, {@code isPresent()} will return {@code true} and
 * {@code get()} will return the value.
 */
 public final class Optional<T> {

    /**
     * Common instance for {@code empty()}.
     */
    private static final Optional<?> EMPTY = new Optional<>(); //执行Optional的无参构造
    
	//无参构造
	private Optional() {
        this.value = null;
    }
    //有参构造
    private Optional(T value) {
        this.value = Objects.requireNonNull(value);
    }
    /**
     * Returns an {@code Optional} describing the specified value, if non-null,
     * otherwise returns an empty {@code Optional}.
     * 如果value不是null, 返回它自己本身, 是空, 则执行empty(), 返回null
     *
     * @param  the class of the value
     * @param value the possibly-null value to describe
     * @return an {@code Optional} with a present value if the specified value
     * is non-null, otherwise an empty {@code Optional}
     */
    public static <T> Optional<T> ofNullable(T value) {
        return value == null ? empty() : of(value);
    }
    /**
     * Returns an empty {@code Optional} instance.  No value is present for this
     * Optional.
     * 当value是空时, 返回Optional对象
     *
     * @apiNote Though it may be tempting to do so, avoid testing if an object
     * is empty by comparing with {@code ==} against instances returned by
     * {@code Option.empty()}. There is no guarantee that it is a singleton.
     * Instead, use {@link #isPresent()}.
     *
     * @param  Type of the non-existent value
     * @return an empty {@code Optional}
     */
    public static<T> Optional<T> empty() {
        @SuppressWarnings("unchecked")
        Optional<T> t = (Optional<T>) EMPTY;  //由第一行代码可知, EMPTY是一个无参Optional对象
        return t;
    }
   
    /**
     * Returns an {@code Optional} with the specified present non-null value.
     * 返回不等于null的value值本身
     *
     * @param  the class of the value
     * @param value the value to be present, which must be non-null
     * @return an {@code Optional} with the value present
     * @throws NullPointerException if value is null
     */ 
    public static <T> Optional<T> of(T value) {
        return new Optional<>(value);  //执行Optional的有参构造
    }
 }

所以大家懂了吗? ofNullable() 就是做了null值判断, 所以我们直接调用此方法就可以了, 而不需要我们自己手动判断null值 。

而 orElse(),orElseGet() ,orElseThrow() 这三个方法都是用来处理null值的情况:

orElse() : 当值为null时, 返回的是该方法的参数 。但值不为null时, 返回值本身。

源码 :

    /**
     * Return the value if present, otherwise return {@code other}.
     * 如果值存在(即不等于空), 返回值本身, 如果等于空, 就返回orElse()方法的参数other.
     *
     * @param other the value to be returned if there is no value present, may
     * be null
     * @return the value, if present, otherwise {@code other}
     */
    public T orElse(T other) {
        return value != null ? value : other;
    }

使用示例 :

如果ofNullable()不等于null, 则返回scRespDTO.getMsgBody().getSuccess()的值;
如果为null, 则返回false (即返回orElse()的参数)。

//如果ofNullable()不等于null, 则返回scRespDTO.getMsgBody().getSuccess()的值, 
//如果为null, 则返回false (即返回orElse()的参数)
Optional.ofNullable(scRespDTO.getMsgBody().getSuccess()).orElse(false)

orElseGet() : 当值为null时, 返回的是实现了Supplier接口的对象的 get() 值 。但值不为null时, 返回值本身。

源码 :

    /**
     * Return the value if present, otherwise invoke {@code other} and return
     * the result of that invocation.
     * 值如果存在(即不为空), 返回值本身, 如果不存在, 则返回实现了Supplier接口的对象. 
     * Supplier接口就只有一个get()方法. 无入参,出参要和Optional的对象同类型.
     *
     * @param other a {@code Supplier} whose result is returned if no value
     * is present
     * @return the value if present otherwise the result of {@code other.get()}
     * @throws NullPointerException if value is not present and {@code other} is
     * null
     */
    public T orElseGet(Supplier<? extends T> other) {
        return value != null ? value : other.get();
    }

使用示例 :

// orElseGet 它可以传入一个supplier接口,里面可以花样实现逻辑
System.out.println(Optional.ofNullable("努力成为一名更优秀的程序媛").orElseGet(()->"你不够优秀"));  // ofNullable()不为空,就输出"努力成为一名更优秀的程序媛",反之,则输出"你不够优秀"
System.out.println(Optional.ofNullable(null).orElseGet(()->"你没有努力"));  // ofNullable()为null, 输出 "你没有努力"

【Tip: 肯定有很多小伙伴觉得 orElse() 和 orElseGet() 方法没有区别,当值为null时,两者都是返回这两方法的参数。但是区别就是,orElseGet() 并不是直接返回参数本身,而是返回参数的get()值,且该参数对象必须实现 supplier 接口(该接口为函数式接口)。这样使得orElseGet()更加灵活。

orElseThrow() : 当值为null时, 返回的是实现了Supplier接口的对象的 get() 值 。但值不为null时, 返回值本身。

源码:

    /**
     * Return the contained value, if present, otherwise throw an exception
     * to be created by the provided supplier.
     *
     * @apiNote A method reference to the exception constructor with an empty
     * argument list can be used as the supplier. For example,
     * {@code IllegalStateException::new}
     *
     * @param  Type of the exception to be thrown
     * @param exceptionSupplier The supplier which will return the exception to
     * be thrown
     * @return the present value
     * @throws X if there is no value present
     * @throws NullPointerException if no value is present and
     * {@code exceptionSupplier} is null
     */
    public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
        if (value != null) {
            return value;
        } else {
            throw exceptionSupplier.get();
        }
    }

使用示例 :

如果ofNullable()不等于null,则返回值本身,即user对象;
如果为null, 则发生指定的异常。(可以使用 :: 形式,这个冒号后面是自定义异常,还可以使用 Lambda 表达式直接引用Java类定义的异常。示例已演示了。)

	//如果user对象为null,且new实现了异常,就以new的形式抛异常,否则抛ArithmeticException异常
	Optional.ofNullable(user).orElseThrow(ArithmeticException::new)); 
	
	//如果user对象不为null,返回该对象,否则抛NullPointerException。异常
	//orElseThrow()如果存在该值,返回包含的值,否则抛出由 Supplier 继承的异常
	Optional.ofNullable(user).orElseThrow(() -> new NotFoundException("记录不存在"));

大家知道了吗?有没有帮助到你们呢?可以评论告诉我哦。
无论如何我们一起努力成长吖~ 成为一名更优秀的程序媛

你可能感兴趣的:(Java,java,lambda)