在 Java 里,Optional 的本意不是用来“消灭 null”,而是用来明确表达“可能没有值”,从而强制调用方处理缺失情况,避免在错误的地方出现 NullPointerException。
下面从「常见错误用法」和「正确避免空的方式」两方面说。
✅ Optional 用来做返回值(尤其是可能为空的结果)
❌ 不要用来做字段、参数、集合元素
Optional 包字段(错误)class User {
Optional<String> name; // ❌ 不推荐
}
问题:
null(Optional 本身可为 null)✅ 正确做法:
class User {
String name; // 允许 null
}
Optional.get() 直接调用(最危险)Optional<String> opt = Optional.ofNullable(null);
String s = opt.get(); // ❌ 直接 NPE
✅ 正确做法(下面详细说)
void foo(Optional<String> name) { } // ❌
调用方可能传 null
✅ 更好的方式:
void foo(String name) {
if (name != null) { }
}
public Optional<User> findUser(Long id) {
return Optional.ofNullable(userRepository.get(id));
}
调用方必须面对“可能没有”:
Optional<User> userOpt = findUser(1L);
orElse(有默认值)String name = userOpt
.map(User::getName)
.orElse("未知");
orElseGet(懒加载)String name = userOpt
.map(User::getName)
.orElseGet(() -> generateDefaultName());
orElseThrow(业务异常)User user = userOpt
.orElseThrow(() -> new RuntimeException("用户不存在"));
ifPresent(只处理有值情况)userOpt.ifPresent(user -> {
System.out.println(user.getName());
});
String city = Optional.ofNullable(user)
.map(User::getAddress)
.map(Address::getCity)
.orElse("未知");
等价于以前:
if (user != null
&& user.getAddress() != null
&& user.getAddress().getCity() != null) {
city = user.getAddress().getCity();
}
Optional<User> adult = userOpt
.filter(u -> u.getAge() >= 18);
❌ 以下场景不要用 Optional:
List<Optional<T>> 是反模式)✅ 集合本身就用空集合代替 null:
List<User> users = Collections.emptyList();
Optional 不是“防 null 工具”,而是“强制你思考有没有值”的设计工具。
如果你愿意,我可以:
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。