应优先使用orElseGet而非orElse,因其支持Lambda且仅在值为空时延迟执行Supplier;嵌套取值可用map链式穿透,最后用orElseGet兜底;无需转换时跳过map直接orElse;业务默认值勿用orElseThrow。

用 Lambda 配合 Optional 实现“判空赋值”,其实是个常见误解——Lambda 表达式本身不参与判空逻辑,真正起作用的是 Optional 的链式方法(如 orElse、orElseGet),而 orElseGet 的参数才支持 Lambda。关键在于:用对方法,让判空和默认值生成解耦且延迟执行。
优先用 orElseGet 而非 orElse
orElse 会**立即执行**传入的默认值表达式,哪怕对象不为空;orElseGet 则只在值为空时才调用 Supplier(可用 Lambda 表示),避免无谓开销。
// ❌ 不推荐:每次都会 new ArrayList(),即使 user.getAddress() 不为空
List<String> tags = Optional.ofNullable(user.getAddress())
.map(Address::getTags)
.orElse(new ArrayList<>());
// ✅ 推荐:仅当为空时才创建新列表
List<String> tags = Optional.ofNullable(user.getAddress())
.map(Address::getTags)
.orElseGet(ArrayList::new);
嵌套取值 + 默认构造一体化
多层判空(如 user → profile → avatarUrl)可一路用 map 向下穿透,最后用 orElseGet 提供兜底逻辑,整条链天然空安全。
// 获取用户头像 URL,任意环节为空都返回默认图地址
String avatar = Optional.ofNullable(user)
.map(User::getProfile)
.map(Profile::getAvatarUrl)
.orElseGet(() -> "https://example.com/default-avatar.png");
避免 map + orElse 的冗余组合
如果只是“有则用原值,无则用默认值”,不需要 map;强行套 map 反而绕弯。直接用 Optional.ofNullable(x).orElse(y) 或更简洁的 Objects.requireNonNullElse(x, y)(Java 9+)。
- 需要转换值(比如 String → Integer)→ 用
map+orElseGet - 只需兜底,不转换 → 跳过 map,直奔
orElse/orElseGet - 连 Optional 都嫌重?考虑
Objects.nonNull(x) ? x : y,语义更直白
慎用 orElseThrow 做业务校验
它适合“空即异常”的场景(如配置项缺失),但别把它当成流程控制手段。抛异常是重量级操作,不应替代常规默认值逻辑。
// 合理:关键 ID 缺失必须中断
Long orderId = Optional.ofNullable(params.get("order_id"))
.map(Long::parseLong)
.orElseThrow(() -> new IllegalArgumentException("order_id required"));
// 不合理:用异常代替默认值,增加栈开销且掩盖真实意图
String name = Optional.ofNullable(user.getName())
.orElseThrow(() -> new RuntimeException("name missing")) // ❌ 改用 orElse("Unknown")

















