Optional介绍以及常用方法使用
`Optional` 是 Java 8 引入的一个容器类,用于更优雅地处理可能为 `null` 的值,避免空指针异常(`NullPointerException`)。它通过函数式风格的方法链,强制开发者显式处理空值逻辑。以下是 `Optional` 的详细用法和最佳实践:
---
### **1. 创建 Optional 对象**
| 方法 | 说明 | 示例 |
|------|------|------|
| `Optional.of(value)` | 创建一个非空 `Optional`,若 `value` 为 `null` 则抛出 `NullPointerException` | `Optional.of("Hello")` |
| `Optional.ofNullable(value)` | 允许 `value` 为 `null`,若 `value` 为 `null` 返回 `Optional.empty()` | `Optional.ofNullable(null)` |
| `Optional.empty()` | 直接创建一个空的 `Optional` 对象 | `Optional.empty()` |
---
### **2. 核心操作方法**
#### **(1) 值是否存在检查**
```java
Optional<String> opt = Optional.ofNullable("test");
// 传统检查方式
if (opt.isPresent()) {
String value = opt.get();
}
// 更推荐:直接消费存在的值(避免显式 get())
opt.ifPresent(value -> System.out.println(value));
```
#### **(2) 提供默认值**
```java
String result = opt.orElse("default"); // 值存在时返回原值,否则返回默认值
String result = opt.orElseGet(() -> calculateDefault()); // 延迟计算默认值(推荐性能敏感场景)
```
#### **(3) 异常处理**
```java
String result = opt.orElseThrow(() -> new RuntimeException("Value not found"));
```
#### **(4) 链式转换与过滤**
```java
// 将值转换为大写(如果存在)
Optional<String> upper = opt.map(String::toUpperCase);
// 过滤出长度大于 3 的值
Optional<String> filtered = opt.filter(s -> s.length() > 3);
// 更复杂的转换(例如调用另一个可能返回 Optional 的方法)
Optional<Integer> length = opt.flatMap(s -> Optional.of(s.length()));
```
---
### **3. 最佳实践**
#### **(1) 避免 `isPresent() + get()` 的显式检查**
```java
// 不推荐 ❌
if (opt.isPresent()) {
String value = opt.get();
// ... 处理 value
}
// 推荐 ✅
opt.ifPresent(value -> {
// ... 直接处理 value
});
```
#### **(2) 优先使用 `orElse()` 或 `orElseThrow()` 代替 `get()`**
```java
// 不推荐 ❌(可能抛出 NoSuchElementException)
String value = opt.get();
// 推荐 ✅
String value = opt.orElse("default");
String value = opt.orElseThrow(() -> new IllegalStateException("Missing value"));
```
#### **(3) 避免嵌套 Optional**
```java
// 不推荐 ❌(Optional<Optional<String>> 难以处理)
Optional<Optional<String>> badNested = opt.map(s -> anotherOptional);
// 推荐 ✅ 使用 flatMap
Optional<String> flattened = opt.flatMap(s -> anotherOptional);
```
#### **(4) 不要滥用 Optional**
- **不适合的场景**:集合类型(如 `List`)、方法参数、POJO 的字段等。
- **适合的场景**:返回值(明确表示可能为 `null`)、链式处理逻辑。
---
### **4. 实际应用示例**
#### **(1) 替换传统 null 检查**
```java
// 传统方式
String spare3 = etcobubusiness.getSpare3();
if (spare3 != null && !spare3.isEmpty()) {
// ... 处理 spare3
}
// Optional 方式
Optional.ofNullable(etcobubusiness.getSpare3())
.filter(s -> !s.isEmpty())
.ifPresent(spare3 -> {
// ... 处理 spare3
});
```
#### **(2) 链式处理复杂逻辑**
```java
Optional.ofNullable(user)
.map(User::getAddress)
.map(Address::getCity)
.orElse("Unknown City");
```
#### **(3) 与 Stream API 结合**
```java
List<String> names = users.stream()
.map(User::getName)
.map(Optional::ofNullable)
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());
```
---
### **5. 常见陷阱**
1. **不要用 `Optional` 代替 `null` 检查**:
```java
// 错误!Optional 本身可能为 null
Optional<String> opt = null;
```
2. **避免在类字段或方法参数中使用 `Optional`**:
```java
// 不推荐 ❌
public class User {
private Optional<String> email; // 增加复杂度
}
```
---
### **总结**
`Optional` 的核心目标是**明确表达“值可能不存在”的语义**,并通过函数式方法链减少空指针异常。合理使用可显著提升代码可读性,但需注意避免滥用。
浙公网安备 33010602011771号