1.简介
Optional类位于java.util包下,是一个可以为 null 的容器对象,如果值存在则isPresent()方法会返回 true ,调用 get() 方法会返回该对象,可以有效避免空指针异常。

2.创建

public class CreateOptional {
    public static void main(String[] args) {
    	//创建一个StringBuilder对象
        StringBuilder stringBuilder = new StringBuilder("我是一个字符串");

        //1.使用Optional.ofNullable(T t)方法,创建Optional对象,注意t允许为空
        StringBuilder nullStringBuilder = null;
        Optional<StringBuilder> stringBuilderOptional = Optional.ofNullable(nullStringBuilder);
        System.out.println(stringBuilderOptional);
        
        //2.使用Optional.of(T t)方法,创建Optional对象,注意T不能为空
        Optional<StringBuilder> stringBuilderOptional2 = Optional.of(stringBuilder);
        System.out.println(stringBuilderOptional2);

        //3.使用Optional.empty()方法,创建一个空的Optional对象:
        Optional<Object> empty = Optional.empty();
        System.out.println(empty);
    }
}

3.常用方法
(1).抛空指针异常

public class OptionalMethods {
    @ToString
    @AllArgsConstructor
    @Data
    static class Category {
        private String name;
    }

    @ToString
    @NoArgsConstructor
    @AllArgsConstructor
    @Data
    static class Goods {
        private String name;

        private Category category;
    }

    /**
     * 获取商品的分类名称
     * @param goods 商品
     * @return 分类名称
     */
    static String getGoodsCategoryName(Goods goods) {
        return goods.getCategory().getName();
    }

    public static void main(String[] args) {
        //实例化一个商品类
        Goods goods = new Goods();
        //获取商品的分类名称
        String categoryName = getGoodsCategoryName(goods);
        System.out.println(categoryName);
    }
}
Exception in thread "main" java.lang.NullPointerException
	at com.example.demo.OptionalMethods.getGoodsCategoryName(OptionalMethods.java:32)
	at com.example.demo.OptionalMethods.main(OptionalMethods.java:39)

实例中,由于在实例化Goods类时,没有给其下面的Category类型的category属性赋值,它就为 null,在运行时,null.getName()就会抛出空指针异常。同理,如果goods实例为null,那么null.getCategory()也会抛出空指针异常。

(2).优化

static String getGoodsCategoryName(Goods goods) {
    if (goods != null) {
        Category category = goods.getCategory();
        if (category != null) {
            return category.getName();
        }
    }
    return "该商品无分类";
}

(3).引入Optional类解决空指针异常

public class OptionalMethods {
    @ToString
    @AllArgsConstructor
    @Data
    static class Category {
        private String name;
    }

    @ToString
    @NoArgsConstructor
    @AllArgsConstructor
    @Data
    static class Goods {
        private String name;

        private Category category;
    }

    /**
     * 获取商品的分类名称
     *
     * @param goods 商品
     * @return 分类名称
     */
    static String getGoodsCategoryName(Goods goods) {
        //将商品实例包装入Optional类,创建Optional<Goods>对象
        Optional<Goods> goodsOptional = Optional.ofNullable(goods);
        //如果有值则将其返回,否则返回指定的默认对象
        Goods defaultGoods = goodsOptional.orElse(new Goods("默认商品", new Category("默认分类")));
        //此时defaultGoods一定是非空,不会产生空指针异常
        Category category = defaultGoods.getCategory();

        //将分类实例包装入Optional类,创建Optional<Category>对象
        Optional<Category> categoryOptional = Optional.ofNullable(category);
        //如果有值则将其返回,否则返回指定的默认对象
        Category defaultCategory = categoryOptional.orElse(new Category("默认分类"));
        //此时defaultCategory一定是非空,不会产生空指针异常
        return defaultCategory.getName();
    }

    public static void main(String[] args) {
        //实例化一个商品类
        Goods goods = new Goods();
        //获取商品的分类名称
        String categoryName = getGoodsCategoryName(goods);
        System.out.println(categoryName);
    }
}

实例中,使用Optional类的ofNullable(T t)方法分别包装了goods对象及其级联属性category对象,允许对象为空,然后又调用了其ofElse(T t)方法保证了对象一定非空。这样,空指针异常就被优雅地规避了。