使用 JDK 1.8 新特性判断对象是否为空
在 Java 1.8 中,Optional 类是最优雅的判空解决方案,它通过函数式编程方式避免 NullPointerException
。以下是具体实现方法:
1. 基础判空(对象整体为空)
// 传统方式
if (user != null) {
// 业务逻辑
}
// JDK 1.8 Optional方式
Optional<User> userOpt = Optional.ofNullable(user);
if (userOpt.isPresent()) { // 等价于 user != null
// 业务逻辑
}
2. 链式安全访问(避免嵌套 null)
// 传统方式(多层判空易出错)
String city = null;
if (user != null && user.getAddress() != null) {
city = user.getAddress().getCity();
}
// JDK 1.8 Optional链式调用
String city = Optional.ofNullable(user)
.map(User::getAddress) // 安全获取Address对象
.map(Address::getCity) // 安全获取City属性
.orElse("默认城市"); // 为空时返回默认值
3. 空值处理(提供默认值/异常)
// 场景1:为空时返回默认值
String name = Optional.ofNullable(user)
.map(User::getName)
.orElse("匿名用户"); // 为空返回"匿名用户"
// 场景2:为空时抛出定制异常
User safeUser = Optional.ofNullable(user)
.orElseThrow(() -> new UserNotFoundException("用户不存在"));
4. 条件触发(非空时执行操作)
Optional.ofNullable(user)
.ifPresent(u -> {
System.out.println("用户名: " + u.getName());
u.activate(); // 非空时执行方法
});
5. 集合判空(Stream API 结合)
List<String> list = null;
// 安全操作空集合
Optional.ofNullable(list)
.orElseGet(Collections::emptyList) // 空时返回空集合
.stream()
.filter(s -> s.length() > 3)
.forEach(System.out::println);
最佳实践原则
避免
Optional.get()
直接调用get()
会抛出NoSuchElementException
,应优先使用orElse()
/orElseGet()
不要用 Optional 包装集合
空集合应用Collections.emptyList()
表示,而非Optional<List>
方法返回值优先返回 Optional
public Optional<Address> findAddress(User user) { return Optional.ofNullable(user) .map(User::getAddress); }
与传统判空对比
传统方式 | Optional 方式 | 优势 |
---|---|---|
if (obj != null) |
Optional.isPresent() |
链式调用避免嵌套 if |
多层属性访问需嵌套判空 | .map() 自动处理中间 null |
代码简洁性提升 50%+ |
需显式处理空值 | .orElse() 声明式处理 |
减少空指针异常风险 |
设计哲学:Optional 不是用来替代所有 null 检查,而是通过类型系统显式标记可能为空的值,强制调用方处理空值情况。
相关问题
- Optional 的
map()
和flatMap()
方法有什么区别? - 为什么说滥用 Optional 可能导致性能问题?
- 如何在 Spring Boot 的 Service 层统一处理 Optional 返回值?
- Java 8 的 Stream API 如何与 Optional 结合处理集合空值?
- Optional 与 Kotlin 的可空类型(?)有何异同?