好的,我们来系统讲解 Java 中的 Optional,帮助你理解它的作用、学习用法,并附上实践示例。


一、Optional 的概念

Optional<T> 是 Java 8 引入的一个容器类,用来 防止 NullPointerException (NPE),表示 一个值可能存在,也可能不存在

  • 特点
    1. 可以包含一个非 null 值,也可以为空(empty)。
    2. 提供了丰富的方法操作值而不需要显式判断 null。
    3. 鼓励使用函数式风格进行处理。

二、Optional 的常用创建方法

import java.util.Optional;

public class OptionalDemo {
    public static void main(String[] args) {
        // 1. of(T value):创建一个非 null Optional
        Optional&lt;String> opt1 = Optional.of("Hello");

        // 2. ofNullable(T value):允许 null 值
        Optional&lt;String> opt2 = Optional.ofNullable(null);

        // 3. empty():创建一个空 Optional
        Optional&lt;String> opt3 = Optional.empty();
    }
}


三、Optional 的常用方法

方法说明
isPresent()判断值是否存在
ifPresent(Consumer<? super T> action)如果值存在,执行 action
orElse(T other)值存在则返回,否则返回 other
orElseGet(Supplier<? extends T> other)值存在则返回,否则执行 Supplier 获取值
orElseThrow(Supplier<? extends Throwable> exceptionSupplier)值存在则返回,否则抛异常
map(Function<? super T,? extends U> mapper)对值执行函数映射,并返回 Optional
flatMap(Function<? super T, Optional<U>> mapper)对值执行函数映射,返回 Optional(避免嵌套 Optional)
filter(Predicate<? super T> predicate)值存在且满足条件返回 Optional,否则返回 empty

四、Optional 使用示例

1. 避免 NullPointerException

Optional&lt;String> name = Optional.ofNullable(getUserName());
String result = name.orElse("Default Name");
System.out.println(result);

如果 getUserName() 返回 null,orElse 会提供默认值。


2. 使用 ifPresent

Optional&lt;String> email = Optional.ofNullable(getUserEmail());
email.ifPresent(e -> System.out.println("Email: " + e));

只有在 email 存在时才会打印。


3. 使用 map 和 flatMap

Optional&lt;User> userOpt = Optional.ofNullable(getUser());

String email = userOpt
                .map(User::getProfile)        // map 返回 Optional&lt;Profile>
                .map(Profile::getEmail)       // map 返回 Optional&lt;String>
                .orElse("no-email@example.com");

System.out.println(email);

  • map 可以连续操作,处理可能为 null 的链式调用。
  • 避免了大量的 null 判断:
if (user != null &amp;&amp; user.getProfile() != null) {
    email = user.getProfile().getEmail();
} else {
    email = "no-email@example.com";
}


4. 使用 filter

Optional&lt;String> phoneOpt = Optional.ofNullable(user.getPhone());

phoneOpt.filter(p -> p.startsWith("+86"))
        .ifPresent(p -> System.out.println("Chinese number: " + p));

  • filter 对值做条件筛选,不满足条件会返回 empty。

5. 使用 orElseThrow

Optional&lt;User> userOpt = Optional.ofNullable(getUser());
User user = userOpt.orElseThrow(() -> new RuntimeException("User not found"));

  • 如果 Optional 为空,就会抛出自定义异常。

五、Optional 的最佳实践

  1. 不要在集合中使用 Optional
    • List<Optional<T>> 不推荐。集合本身可以为空或空集合表示不存在。
  2. 不要把 Optional 作为方法参数
    • Optional 更适合方法返回值,作为参数会增加复杂性。
  3. 链式调用处理多层嵌套对象
    • 使用 map + flatMap 避免嵌套 null 判断。
  4. 结合 lambda 表达式提高代码可读性
    • ifPresentorElseGetfilter 都能让代码更简洁。

六、完整示例

import java.util.Optional;

class Profile {
    private String email;
    public Profile(String email) { this.email = email; }
    public String getEmail() { return email; }
}

class User {
    private Profile profile;
    public User(Profile profile) { this.profile = profile; }
    public Profile getProfile() { return profile; }
}

public class OptionalExample {
    public static void main(String[] args) {
        User user = new User(null);

        // 使用 Optional 链式调用获取邮箱
        String email = Optional.ofNullable(user)
                .map(User::getProfile)
                .map(Profile::getEmail)
                .orElse("no-email@example.com");

        System.out.println(email); // 输出 no-email@example.com
    }
}

  • 效果:用一行代码代替多层 null 判断,清晰、可读、健壮。

总结:

  • OptionalJava 8 防止 NPE 的工具
  • 不存储 null,通过 orElse, orElseGet, orElseThrow 等方法处理缺省值。
  • 支持函数式操作链 (map, flatMap, filter),简化嵌套对象处理。
  • 最佳实践:只作为方法返回值,不用于参数或集合。

明白,我帮你画一张 Java Optional 使用流程图,可视化整个操作流程,从创建到获取值。

下面是文字版流程图说明,我会生成对应可视化图:


Java Optional 使用流程图(文字版)

开始
  │
  ▼
创建 Optional
  │
  │-- of(value) → 必须非 null
  │-- ofNullable(value) → 允许 null
  │-- empty() → 空 Optional
  │
  ▼
判断是否存在
  │
  │-- isPresent() → true/false
  │-- ifPresent(Consumer) → 值存在时执行操作
  │
  ▼
值存在时操作
  │
  │-- map(Function) → 对值进行转换,返回 Optional
  │-- flatMap(Function) → 对值进行转换,返回 Optional(避免嵌套)
  │-- filter(Predicate) → 条件判断,不满足返回 empty
  │
  ▼
获取值
  │
  │-- orElse(defaultValue) → 值存在返回值,否则返回默认值
  │-- orElseGet(Supplier) → 值存在返回值,否则调用 Supplier 获取
  │-- orElseThrow(Supplier) → 值存在返回值,否则抛异常
  │
  ▼
结束