1. 概述

在Java中,引用可能指向内存中的对象,也可能不指向——换句话说,引用可能是null。这就埋下了抛出NullPointerException的隐患。

为了解决这个问题,Java 8引入了Optional类。将引用包装在Optional中,能更清晰地表达值可能存在或不存在的情况。此外,我们可以利用Optional类的各种工具方法(如isPresent())来避免NullPointerException

我们可以通过静态工厂方法Optional.of()Optional.ofNullable()来获取引用的Optional对象。但该用哪个呢?本文将深入探讨两者的区别,并说明各自的使用场景。

2. Optional.of()方法

当我们确定引用非null时,应该使用Optional.of()静态工厂方法

假设有一个局部String变量,我们想获取它的Optional对象:

@Test
void givenNonNullReference_whenUsingOptionalOf_thenObtainOptional() {
    String s = "no null here";
    assertThat(Optional.of(s))
      .isNotEmpty()
      .hasValue("no null here");
}

从断言可以看出,这个Optional非空。也就是说,isPresent()方法会返回true

**但踩坑点来了:如果对null引用使用此方法,会直接抛出NullPointerException**:

@Test
void givenNullReference_whenUsingOptionalOf_thenNullPointerExceptionThrown() {
    String s = null;
    assertThatThrownBy(() -> Optional.of(s))
      .isInstanceOf(NullPointerException.class);
}

3. Optional.ofNullable()方法

当引用可能为null时,应该使用Optional.ofNullable()静态工厂方法。**这样即使引用是null,也不会抛出异常,而是返回一个空的Optional**:

@Test
void givenNullReference_whenUsingOptionalOfNullable_thenObtainOptional() {
    String s = null;
    assertThat(Optional.ofNullable(s)).isEmpty();
}

你可能会问:为什么不总是用Optional.ofNullable()替代Optional.of()

使用Optional.of()的好处在于:当引用为null时,它会立即抛出异常终止程序执行。这符合"快速失败"(fail-early)原则——在问题发生的最早阶段暴露错误,而不是让null值在系统中传播。

⚠️ 顺便提一句,有些开发者会把这些静态工厂方法作为函数式编程的入口,通过调用Optionalmap()等方法(接受函数对象作为参数)来实现链式操作。

4. 总结

本文我们深入探讨了Optional.of()Optional.ofNullable()的核心区别,以及各自的最佳使用场景:

Optional.of()

  • 用于确定非null的引用
  • 遇到null会立即抛出NullPointerException
  • 符合"快速失败"原则

Optional.ofNullable()

  • 用于可能为null的引用
  • 遇到null返回空Optional
  • 更安全但可能掩盖问题

通过合理使用Optional类,我们可以有效避免NullPointerException。同时,是否遵循"快速失败"原则,也会影响我们对这两个静态工厂方法的选择。

本文所有代码示例可在GitHub仓库中获取。


原始标题:Difference Between Optional.of() and Optional.ofNullable() in Java | Baeldung