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)方法保证了对象一定非空。这样,空指针异常就被优雅地规避了。