应避免用optional包装非空必返值、嵌套flatmap需拆分、禁用optional作字段/参数、默认值优先用orelseget。语义清晰、性能可控、可读性强。

别用 Optional 包装本不该为空的值
如果一个方法在业务语义上“必须返回结果”,比如 getUserById(Long id) 在用户已被校验存在的情况下调用,强行返回 Optional
嵌套 flatMap 别堆砌,该拆就拆
像这样写会让阅读者绕晕:
❌ 可读性差:
return Optional.ofNullable(user)
.flatMap(u -> Optional.ofNullable(u.getProfile()))
.flatMap(p -> Optional.ofNullable(p.getAvatar()))
.map(Avatar::getUrl)
.orElse(null);
✅ 更推荐分步或提取方法:
– 提取为私有工具方法:getAvatarUrl(User user),内部用 Optional 链式处理,对外接口干净;
– 或用 if 判空(当层级少、逻辑简单时):if (user != null && user.getProfile() != null && ...),反而一目了然。
避免把 Optional 当“万能胶”粘到处
以下做法会显著拖累可读性:
- 把 Optional
name 声明为实体类字段 —— 序列化、JSON 输出、日志打印全变复杂; - 方法参数写成 processUser(Optional
user) —— 调用方得自己决定传 of() 还是 empty(),甚至可能传 null,失去约束力; - 在流操作里滥用 ifPresent() 做非纯函数操作(如修改外部变量、发通知),打断链式语义,不如单独写一段逻辑。
默认值优先用 orElseGet,别塞大表达式
❌ 影响可读又低效:
opt.orElse(loadFromDatabase()) —— 每次都执行查询,不管 opt 是否有值。
✅ 清晰且高效:
opt.orElseGet(() -> loadFromDatabase()) —— 只在缺失时触发,意图明确,性能可控。
同理,orElseThrow(() -> new XxxException("id=" + id)) 比裸调 get() 报错信息更完整,调试时一眼定位问题。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











