面试实战 问题二十七 java 使用1.8新特性,判断空
使用 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 的可空类型(?)有何异同?