好的阿杰,我给你做一个 通俗易懂、系统化的 Java Optional 教程,包括理解、学习和实际使用场景。


1️⃣ 什么是 Optional

Optional 是 Java 8 引入的一个容器类,用于防止 NullPointerException(NPE)

核心思想

  • 让返回值显式地表示可能为空
  • 避免 if (obj != null) 的繁琐判断
  • 提高代码可读性与安全性

本质Optional<T> 可以包含一个类型为 T 的对象,或者什么都不包含(empty)。


2️⃣ 创建 Optional 对象

import java.util.Optional;

public class OptionalDemo {
    public static void main(String[] args) {
        // 1. 创建空的 Optional
        Optional&lt;String> emptyOpt = Optional.empty();

        // 2. 创建非空 Optional(如果传入 null,会抛异常)
        Optional&lt;String> nameOpt = Optional.of("阿杰");

        // 3. 可空 Optional(可以为 null,不会抛异常)
        Optional&lt;String> nullableOpt = Optional.ofNullable(null);
    }
}


3️⃣ 获取值的方法

1. get()

  • 获取值,如果为空会抛 NoSuchElementException
String name = nameOpt.get();  // 阿杰

2. orElse()

  • 如果值为空,返回默认值
String name = emptyOpt.orElse("默认值"); // 默认值

3. orElseGet()

  • 懒加载默认值,用 Supplier 提供
String name = emptyOpt.orElseGet(() -> "懒加载默认值");

4. orElseThrow()

  • 值为空时抛异常
String name = emptyOpt.orElseThrow(() -> new IllegalArgumentException("值不能为空"));


4️⃣ 判断 Optional 是否有值

if (nameOpt.isPresent()) {
    System.out.println(nameOpt.get());
}

// Java 11 之后,可使用 ifPresentOrElse
nameOpt.ifPresentOrElse(
    val -> System.out.println(val),
    () -> System.out.println("值为空")
);


5️⃣ 常用组合操作

1. map()

  • 对 Optional 中的值进行转换
Optional&lt;Integer> length = nameOpt.map(String::length);
System.out.println(length.get()); // 2 (阿杰长度)

2. flatMap()

  • 避免嵌套 Optional
Optional&lt;Optional&lt;String>> nestedOpt = Optional.of(Optional.of("阿杰"));
Optional&lt;String> flat = nestedOpt.flatMap(o -> o);

3. filter()

  • 根据条件过滤值
Optional&lt;String> filtered = nameOpt.filter(s -> s.startsWith("阿"));
System.out.println(filtered.isPresent()); // true


6️⃣ 使用 Optional 的最佳实践

  1. 返回值使用 Optional
public Optional&lt;User> findUserById(String id) { ... }

  1. 方法参数不要使用 Optional
// ❌ 不推荐
public void updateUser(Optional&lt;User> user) { ... }

  1. 避免 overuse
  • Optional 并不能替代所有 null
  • 对于集合、数组等推荐直接返回空集合,而不是 Optional
  1. 链式调用
String city = userOpt
    .map(User::getAddress)
    .map(Address::getCity)
    .orElse("未知城市");


7️⃣ Optional 的价值总结

特点说明
防止 NPE让空值显式化
提升可读性链式调用代替 if (obj != null)
函数式风格map / flatMap / filter 支持函数式编程
增强安全性提醒调用者处理空值