Java Optional类 #
一、Optional概述 #
1.1 什么是Optional #
Optional是Java 8引入的容器类,用于避免空指针异常。
1.2 Optional好处 #
- 明确表示值可能为空
- 避免空指针异常
- 代码更优雅
二、创建Optional #
2.1 of #
java
// 创建非空Optional
Optional<String> opt1 = Optional.of("Hello");
// Optional.of(null); // NullPointerException
2.2 ofNullable #
java
// 创建可能为空的Optional
Optional<String> opt1 = Optional.ofNullable("Hello");
Optional<String> opt2 = Optional.ofNullable(null);
2.3 empty #
java
// 创建空Optional
Optional<String> empty = Optional.empty();
三、常用方法 #
3.1 isPresent和isEmpty #
java
Optional<String> opt = Optional.ofNullable("Hello");
if (opt.isPresent()) {
System.out.println(opt.get());
}
if (opt.isEmpty()) { // Java 11+
System.out.println("值为空");
}
3.2 get #
java
Optional<String> opt = Optional.of("Hello");
if (opt.isPresent()) {
String value = opt.get();
}
// 空Optional调用get抛NoSuchElementException
// Optional.empty().get(); // 异常
3.3 orElse #
java
Optional<String> opt = Optional.ofNullable(null);
// 如果为空返回默认值
String value = opt.orElse("默认值");
System.out.println(value); // 默认值
3.4 orElseGet #
java
Optional<String> opt = Optional.empty();
// 延迟计算默认值
String value = opt.orElseGet(() -> {
System.out.println("计算默认值");
return "默认值";
});
3.5 orElseThrow #
java
Optional<String> opt = Optional.empty();
// 为空时抛出异常
String value = opt.orElseThrow(() -> new IllegalArgumentException("值不能为空"));
3.6 or(Java 9+) #
java
Optional<String> opt = Optional.empty();
// 为空时返回另一个Optional
Optional<String> result = opt.or(() -> Optional.of("默认值"));
四、函数式方法 #
4.1 ifPresent #
java
Optional<String> opt = Optional.of("Hello");
opt.ifPresent(value -> System.out.println(value));
4.2 ifPresentOrElse(Java 9+) #
java
Optional<String> opt = Optional.empty();
opt.ifPresentOrElse(
value -> System.out.println("值: " + value),
() -> System.out.println("值为空")
);
4.3 map #
java
Optional<String> opt = Optional.of("Hello");
Optional<Integer> length = opt.map(String::length);
System.out.println(length.get()); // 5
4.4 flatMap #
java
Optional<String> opt = Optional.of("Hello");
Optional<Integer> length = opt.flatMap(s -> Optional.of(s.length()));
4.5 filter #
java
Optional<String> opt = Optional.of("Hello World");
Optional<String> filtered = opt.filter(s -> s.length() > 5);
System.out.println(filtered.isPresent()); // true
Optional<String> filtered2 = opt.filter(s -> s.length() > 20);
System.out.println(filtered2.isPresent()); // false
五、Optional使用示例 #
5.1 方法返回值 #
java
public Optional<User> findUserById(Long id) {
User user = userRepository.findById(id);
return Optional.ofNullable(user);
}
// 使用
Optional<User> user = findUserById(1L);
String name = user.map(User::getName).orElse("未知用户");
5.2 链式调用 #
java
public String getCity(User user) {
return Optional.ofNullable(user)
.map(User::getAddress)
.map(Address::getCity)
.orElse("未知城市");
}
5.3 参数校验 #
java
public void process(String input) {
String value = Optional.ofNullable(input)
.filter(s -> !s.isEmpty())
.orElseThrow(() -> new IllegalArgumentException("输入不能为空"));
}
5.4 集合处理 #
java
List<String> list = getList();
List<String> safeList = Optional.ofNullable(list)
.orElseGet(ArrayList::new);
六、最佳实践 #
6.1 不要用Optional作为字段 #
java
// 不推荐
public class User {
private Optional<String> nickname; // 不推荐
}
// 推荐
public class User {
private String nickname; // 可以为null
}
6.2 不要用Optional作为方法参数 #
java
// 不推荐
public void process(Optional<String> value) { }
// 推荐
public void process(String value) { }
public void process(@Nullable String value) { }
6.3 不要直接调用get #
java
Optional<String> opt = Optional.ofNullable(getString());
// 不推荐
if (opt.isPresent()) {
String value = opt.get();
}
// 推荐
opt.ifPresent(value -> process(value));
String value = opt.orElse("默认值");
6.4 选择合适的默认值方法 #
java
// orElse:默认值已确定
String value1 = opt.orElse("默认值");
// orElseGet:默认值需要计算
String value2 = opt.orElseGet(() -> computeDefaultValue());
// orElseThrow:需要抛出异常
String value3 = opt.orElseThrow(() -> new RuntimeException("值不能为空"));
七、Optional原始类型 #
7.1 OptionalInt #
java
OptionalInt optInt = OptionalInt.of(100);
OptionalInt empty = OptionalInt.empty();
int value = optInt.orElse(0);
7.2 OptionalLong #
java
OptionalLong optLong = OptionalLong.of(100L);
long value = optLong.orElse(0L);
7.3 OptionalDouble #
java
OptionalDouble optDouble = OptionalDouble.of(3.14);
double value = optDouble.orElse(0.0);
八、总结 #
| 方法 | 说明 |
|---|---|
| of | 创建非空Optional |
| ofNullable | 创建可能为空的Optional |
| empty | 创建空Optional |
| isPresent | 判断是否有值 |
| get | 获取值(可能抛异常) |
| orElse | 返回值或默认值 |
| orElseGet | 返回值或计算默认值 |
| orElseThrow | 返回值或抛异常 |
| map | 映射值 |
| filter | 过滤值 |
Optional要点:
- 用于方法返回值
- 避免直接调用get
- 选择合适的默认值方法
- 不要用于字段和参数
最后更新:2026-03-26