在Java业务代码里,我们经常会从某个对象一路取属性,比如从订单取用户,再从用户取地址,最后取城市名称。只要中间某一层是null,直接调用方法就会抛出NullPointerException。过去只能写很多if来判断,既乱又容易漏。Optional类提供了更干净的处理方式。

传统写法的问题
假设有Order、User、Address三个类,我们要拿到用户的城市名。传统代码可能写成这样:
// 传统嵌套判空
public String getCityOld(Order order) {
if (order != null) {
User user = order.getUser();
if (user != null) {
Address addr = user.getAddress();
if (addr != null) {
return addr.getCity();
}
}
}
return "未知";
}
这种写法嵌套深,可读性差,而且新增层级时更容易出错。
使用Optional简化多级导航
Optional可以用map把值转换,用flatMap处理返回Optional的方法,从而避免显式判空。
import java.util.Optional;
public String getCityNew(Order order) {
return Optional.ofNullable(order)
.map(Order::getUser)
.map(User::getAddress)
.map(Address::getCity)
.orElse("未知");
}
上面代码中,ofNullable允许order为null,每一层map在值为null时直接返回空Optional,最后用orElse给出默认值。
需要flatMap的场景
如果某个取值方法本身返回Optional,就要用flatMap,否则会出现Optional嵌套。
// 假设getUser返回Optional<User>
public String getCityFlat(Order order) {
return Optional.ofNullable(order)
.flatMap(Order::getUser)
.map(User::getAddress)
.map(Address::getCity)
.orElse("未知");
}
结合filter做条件拦截
有时我们不仅怕null,还要过滤不合条件的数据。比如只要激活用户才取城市。
public String getCityIfActive(Order order) {
return Optional.ofNullable(order)
.map(Order::getUser)
.filter(user -> user.isActive())
.map(User::getAddress)
.map(Address::getCity)
.orElse("未激活或未知");
}
使用Optional的注意事项
- 不要将Optional作为类字段或方法参数,它只适合返回值包装。
- 避免用isPresent加get代替普通判空,那样并没有更简洁。
- 不要为了链式而链式,简单一层判空直接if可能更直观。
合理运用Optional的map、flatMap、filter和orElse,可以让多级对象导航中的null处理变得整洁安全,也更符合现代Java风格。