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
值在系统中传播。
⚠️ 顺便提一句,有些开发者会把这些静态工厂方法作为函数式编程的入口,通过调用Optional
的map()
等方法(接受函数对象作为参数)来实现链式操作。
4. 总结
本文我们深入探讨了Optional.of()
和Optional.ofNullable()
的核心区别,以及各自的最佳使用场景:
✅ Optional.of()
- 用于确定非
null
的引用 - 遇到
null
会立即抛出NullPointerException
- 符合"快速失败"原则
✅ Optional.ofNullable()
- 用于可能为
null
的引用 - 遇到
null
返回空Optional
- 更安全但可能掩盖问题
通过合理使用Optional
类,我们可以有效避免NullPointerException
。同时,是否遵循"快速失败"原则,也会影响我们对这两个静态工厂方法的选择。
本文所有代码示例可在GitHub仓库中获取。