optional 的核心是将“值可能不存在”作为明确业务语义,仅用于方法返回值,避免用作字段或参数;创建用 ofnullable(),取值优先 orelse/ifpresent,链式 map 解决嵌套空值。

用 Optional 彻底告别 NullPointerException,关键不在“多写几个方法”,而在于转变思维:把“值可能不存在”当成一种明确的业务语义,而不是靠运气躲开 null。它不是万能胶,但用对了,能让空值处理从易错、冗长、隐晦,变成安全、简洁、自解释。
只在该用的地方返回 Optional
Optional 的核心定位是方法返回值容器,不是通用包装器。它表达的是“这个结果天然就可能没有”——比如查数据库没找到用户、配置项未设置、远程调用超时返回空响应。
- ✅ 推荐:public Optional
findUserById(Long id) - ❌ 避免:private Optional
name;(成员变量) - ❌ 避免:public void process(Optional
order)(入参)
当成字段或参数,反而模糊了语义,增加调用方理解成本,也违背了“显式表达可选性”的初衷。
创建时认准 ofNullable() 为主力
日常开发中,绝大多数需要包装的对象你都无法 100% 确定它非 null。这时候无脑用 ofNullable() 就对了,它既不抛异常,也不要求你提前判空,一步到位。
- String raw = request.getParameter("name");
- Optional
nameOpt = Optional.ofNullable(raw); // 安全,无论 raw 是 "张三"、"" 还是 null,都 OK
of() 只用于你已通过其他手段(如校验注解、前置断言)确保非空的场景;empty() 则用于逻辑上明确要返回“无结果”的分支,比如缓存未命中且不打算触发回源。
取值别用 get(),优先走 orElse / ifPresent
get() 是 Optional 的“危险按钮”——它假设值一定存在,一旦为空就立刻抛 NoSuchElementException。这和用 null 没本质区别,只是换了个异常类型。
- ✅ 推荐:String name = nameOpt.orElse("匿名用户"); // 有则取,无则给默认
- ✅ 推荐:nameOpt.ifPresent(n -> log.info("欢迎 {}", n)); // 有才执行,无则静默跳过
- ❌ 谨慎:String name = nameOpt.get(); // 除非你 100% 确信 isPresent() 为 true
orElseGet() 更进一步,适合默认值生成开销大(比如查库、发 HTTP 请求)的场景,它只在真正需要时才执行 Supplier。
链式调用解决“箭头地狱”
面对 user.getAddress().getCity().getName() 这类多层嵌套,传统写法是层层 if 判空。Optional 的 map() 让你把转换逻辑“挂”在值上,空值自动短路,无需手动拦截。
- Optional
cityName = Optional.ofNullable(user) - .map(User::getAddress)
- .map(Address::getCity)
- .map(City::getName);
整条链只要中间任意一环为 null,结果就是 empty(),后续 map 不会执行。最后再用 orElse 或 ifPresent 消费,代码扁平、语义清晰、零 NPE 风险。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











