zoukankan      html  css  js  c++  java
  • Java 8 Optional正确使用姿势

    在Java程序中,空指针异常(NullPointerException)可以说是最常见的的了,所以我们在打代码的时候会到处使用if(null == A){ ...... }这类操作。Java 8提供了Optional类型来一定程度上缓解NPE问题,这里主要因为自己在使用Optional类型时候踩到一些坑,故作此总结加深印象。

    Optional是什么

    Optional是什么?有什么作用?什么时候该用?什么时候最好不用?这里我也不去网上搜索搬定义了,直接读源码类上的注释说明就可以明白了

    package java.util;
    
    import java.util.function.Consumer;
    import java.util.function.Function;
    import java.util.function.Predicate;
    import java.util.function.Supplier;
    import java.util.stream.Stream;
    
    /**    ----Optional是什么----
     * A container object which may or may not contain a non-{@code null} value.
     * If a value is present, {@code isPresent()} returns {@code true}. If no
     * value is present, the object is considered <i>empty</i> and
     * {@code isPresent()} returns {@code false}.
     *    ----Optional的附加方法说明----
     * <p>Additional methods that depend on the presence or absence of a contained
     * value are provided, such as {@link #orElse(Object) orElse()}
     * (returns a default value if no value is present) and
     * {@link #ifPresent(Consumer) ifPresent()} (performs an
     * action if a value is present).
     *    ----什么时候不该用Optional----
     * <p>This is a <a href="../lang/doc-files/ValueBased.html">value-based</a>
     * class; use of identity-sensitive operations (including reference equality
     * ({@code ==}), identity hash code, or synchronization) on instances of
     * {@code Optional} may have unpredictable results and should be avoided.
     *    ----什么时候用Optional----
     * @apiNote
     * {@code Optional} is primarily intended for use as a method return type where
     * there is a clear need to represent "no result," and where using {@code null}
     * is likely to cause errors. A variable whose type is {@code Optional} should
     * never itself be {@code null}; it should always point to an {@code Optional}
     * instance.
     *
     * @param <T> the type of value
     * @since 1.8
     */
    

    正确使用姿势

    1 使用Optional 的目的主要是为了清晰地表达返回值中没有结果的可能性

    所以一般只用来作为方法的返回值类型,例如:

    Optional 是不可变类型,是加了final修饰的类,并且,它是没用共有构造器的,所以我们没办法new出一个Optional 来,我们只能使用它所提供的三个方法来得到Optional 对象:

    // 1 
    public static<T> Optional<T> empty() {
            @SuppressWarnings("unchecked")
            Optional<T> t = (Optional<T>) EMPTY;
            return t;
        }
    
    // 2 
    public static <T> Optional<T> of(T value) {
            return new Optional<>(Objects.requireNonNull(value));
        }
    // 3 
    public static <T> Optional<T> ofNullable(T value) {
            return value == null ? (Optional<T>) EMPTY
                                 : new Optional<>(value);
        }
    

    下面是个人对Optional 使用的一些总结:

    2 不要直接给Optional 赋null值

    3 如果不能保证对象一定不为null,那就用Optional .ofNullable(),因为Optional .of()会抛NPE

        /**
         * Returns an {@code Optional} describing the given non-{@code null}
         * value.
         *
         * @param value the value to describe, which must be non-{@code null}
         * @param <T> the type of the value
         * @return an {@code Optional} with the value present
         * @throws NullPointerException if value is {@code null} //这里明确了value为空会NPE!!!
         */
        public static <T> Optional<T> of(T value) {
            return new Optional<>(Objects.requireNonNull(value));
        }
    
        /**
         * Returns an {@code Optional} describing the given value, if
         * non-{@code null}, otherwise returns an empty {@code Optional}.
         *
         * @param value the possibly-{@code null} value to describe
         * @param <T> the type of the value
         * @return an {@code Optional} with a present value if the specified value
         *         is non-{@code null}, otherwise an empty {@code Optional}
         */
        @SuppressWarnings("unchecked")
        public static <T> Optional<T> ofNullable(T value) {
            return value == null ? (Optional<T>) EMPTY
                                 : new Optional<>(value);
        }
    

    4 使用isEmpty()或isPresent()来作为判断value是否为空,而不是if(optional1 == null) {...}

    5 使用orElse, orElseGet, orElseThrow这几个API来避免自己写if else语句

    6 使用equals方法判断Optional对象是否相等,而不是使用“==”

    因为Optional类已经覆盖了equals方法,所以想必你已经能猜到上面的输出结果了吧

    7 使用filter对value对象做业务逻辑判断

    首先我们在Shop类中加个如下简单的业务逻辑判断方法,然后再进行测试看看结果:

        //在Shop类中加个简单的业务逻辑判断方法
        public Boolean isRecommanded(){
            if (Objects.equals(this.shopId,1L)){
                return true;
            }
            return false;
        }
    

    如果提供给filter中的返回false,那么就会得到一个空的Optional,而这时再调用get方法就会报如上错误,所以在使用Optional的get方法前一定要使用isPresent()方法先判断!

    以上就是个人对Optional学习和使用的一些总结,以此文记录一番

  • 相关阅读:
    Java基础之线程最详细最精简的介绍
    Android基础之Android硬件
    Iphone客户端程序员半年工作总结
    Java基础之synchronized的讲解
    物联网能否落地?可裁剪嵌入式OS成关键
    java基础之Thread与Runnable的区别
    Android基础之小问题集锦
    Java基础之字符串匹配大全
    BPM 是与非 什么是BPM,如何辨别是否BPM产品,以及如何选择BPM产品
    Hello China操作系统的安装和使用
  • 原文地址:https://www.cnblogs.com/kuangdw/p/15023307.html
Copyright © 2011-2022 走看看