Optional核心是显式建模“值可能存在或不存在”的语义,而非替代null检查;它提升API契约清晰度、终结箭头地狱,但禁用于字段/参数/集合,仅推荐作为方法返回类型。

Java 中 Optional 的面试题,核心是考察你是否真正理解它“不是用来替代 null 检查的工具”,而是用于显式建模值可能存在或不存在的语义。答得好,关键在三点:说清设计意图、分清使用边界、避开常见误用。
为什么需要 Optional?不是直接判空更简单吗?
这个问题是在考设计动机。不能只答“避免空指针”,要讲清楚语义升级:
- 传统
if (obj != null)是防御性编程,关注“怎么不崩”,但没表达业务含义;Optional 把“这个值可能没有”变成类型系统的一部分,让接口契约更清晰 - 比如
Optional<user> findUserById(Long id)</user>比User findUserById(Long id)更诚实——调用方一眼知道结果可能为空,必须处理 - 它终结了“箭头地狱”:嵌套判空(user != null && user.getAddress() != null && ...)可被链式调用替代,逻辑更扁平
of、ofNullable、empty 三者区别和使用场景
这是基础辨析题,重点在何时该用哪个构造方法:
-
Optional.of(value):value 绝对不为 null 时用。传 null 直接抛NullPointerException,适合内部已确保非空的场景(如常量、已校验参数) -
Optional.ofNullable(value):最常用。value 可能为 null,安全包装——null → 空 Optional,非 null → 包含该值的 Optional -
Optional.empty():明确返回空结果,比如查询无匹配时,比ofNullable(null)更直白、语义更强
orElse、orElseGet、orElseThrow 怎么选?
考的是对“默认值计算时机”的理解,本质是性能与语义权衡:
立即学习“Java免费学习笔记(深入)”;
-
orElse(defaultValue):无论 Optional 是否有值,defaultValue都会立即求值(即使没用上)。适合轻量、无副作用的默认值,如字符串字面量 -
orElseGet(Supplier):仅当 Optional 为空时才执行 Supplier。适合默认值创建开销大、或有副作用(如查数据库、发日志),避免无谓计算 -
orElseThrow(Supplier<? extends Throwable>):为空时抛异常。推荐用 lambda 表达式明确异常类型和原因,比如orElseThrow(() -> new UserNotFoundException("ID not found: " + id))
map 和 flatMap 的核心差异在哪?
这是函数式操作的关键区分点,容易混淆:
-
map接收Function<T, R>,把 T 映射成 R,然后自动包装成Optional<R>。R 可以是任意类型(String、Integer 等) -
flatMap接收Function<T, Optional<R>>,要求映射结果本身必须是 Optional。它不会二次包装,而是“压平”一层——避免出现Optional<Optional<String>>这种嵌套结构 - 典型场景:连续调用可能返回 Optional 的方法(如
user.getAddress().getCity()),用flatMap链式衔接更自然
不复杂但容易忽略:Optional 不该用在字段、参数或集合元素中;它不是 null 的替代品,而是方法返回类型的契约增强。用错地方反而增加理解成本。


















