optional旨在显式表达“可能为空”,仅适用于返回值;禁用于参数和字段;优先用ofnullable();善用map/flatmap/filter链式操作;必要时用orelsethrow()抛异常。

用 Optional 不是为了消灭 NullPointerException,而是让“可能为空”这个事实显式化、不可忽略,从而从设计上减少空指针隐患。
别用 Optional 包装方法参数或字段
Optional 是为返回值场景设计的。把它当参数传入,调用方反而要额外解包;定义成类字段更会破坏封装性,且序列化、持久化时容易出问题。
- ❌ 错误:public void process(Optional
name) { ... } - ❌ 错误:private Optional
cachedUser; - ✅ 正确:public Optional
findUserById(Long id) { ... }
优先用 ofNullable(),避免无意义的空 Optional
如果对象本身可能是 null,直接用 Optional.ofNullable(obj);不要先判空再手动 new Optional,更不要对已知非空对象用 ofNullable。
- ✅ 推荐:return Optional.ofNullable(userDao.findById(id));
- ❌ 避免:if (user != null) return Optional.of(user); else return Optional.empty();
- ⚠️ 警惕:Optional.ofNullable("hello") —— 字符串确定非空,用
Optional.of("hello")更清晰
链式操作时善用 map/flatMap/filter,少用 get() 和 isPresent()
调用 get() 前没校验等于埋雷;反复写 if (opt.isPresent()) 就失去了 Optional 的表达力。
- ✅ 推荐:userOpt.map(User::getEmail).filter(Email::isValid).orElse("default@example.com")
- ✅ 推荐:orderOpt.flatMap(o -> o.getAddressOpt()).map(Address::getCity).orElse("Unknown")
- ❌ 避免:if (userOpt.isPresent()) return userOpt.get().getName(); else return "Anonymous";
需要明确失败语义时,考虑抛异常而非返回 empty
当“找不到”是异常情况(比如根据主键查用户却没查到),用 orElseThrow() 比返回 Optional.empty() 更能传达业务意图。
- ✅ 明确语义:return userRepository.findById(id).orElseThrow(() -> new UserNotFoundException(id));
- ✅ 同时兼顾日志:userRepository.findById(id).orElseThrow(() -> { log.warn("User {} not found", id); return new UserNotFoundException(id); });










