解读JDK8中的Optional.of和Optional.ofNullable方法的区别和用法

话不多说,因为笔者用他反而报NPE了。。。。

 

通常来说,我使用Optional是用来设置默认值的,杜绝null的出现。但是最近使用Optional.of报空指针了。。

那么我们先看看源码:

    /**
     * Returns an {@code Optional} with the specified present non-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  Optional of(T value) {
        return new Optional<>(value);
    }

    /**
     * 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);
    }

  /**
     * Checks that the specified object reference is not {@code null}. This
     * method is designed primarily for doing parameter validation in methods
     * and constructors, as demonstrated below:
     * 
     * public Foo(Bar bar) {
     *     this.bar = Objects.requireNonNull(bar);
     * }
     * 
* * @param obj the object reference to check for nullity * @param the type of the reference * @return {@code obj} if not {@code null} * @throws NullPointerException if {@code obj} is {@code null} */ public static T requireNonNull(T obj) { if (obj == null) throw new NullPointerException(); return obj; }

顺着方法一步步走查,发现,如果T value是null,那么使用Optional.of(T value)就会手动抛出NullPointerException()。

所以,使用该方法格外注意,不能有null。

 

那么我们该用哪个方法呢:

Optional.ofNullable:

    /**
     * Returns an {@code Optional} describing the specified value, if non-null,
     * otherwise returns an empty {@code Optional}.
     *
     * @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  Optional ofNullable(T value) {
        return value == null ? empty() : of(value);
    }

    /**
     * Returns an empty {@code Optional} instance.  No value is present for this
     * 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 Optional empty() {
        @SuppressWarnings("unchecked")
        Optional t = (Optional) EMPTY;
        return t;
    }

    /**
     * Common instance for {@code empty()}.
     */
    private static final Optional EMPTY = new Optional<>();

    /**
     * Constructs an empty instance.
     *
     * @implNote Generally only one empty instance, {@link Optional#EMPTY},
     * should exist per VM.
     */
    private Optional() {
        this.value = null;
    }

    /**
     * Return the value if present, otherwise return {@code 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;
    }

诶,这个方法可以,如果value为null,那么就会手动创建一个new Optional();但是this.value = null。所以这个时候就跳出了手动抛空指针那个代码块。这个时候,我们就可以使用orElse(T other)。看源码,如果value == null,那么将取other的值。

你可能感兴趣的:(Java)