Java Optional
类详解与常用用法
Optional
是 Java 8 引入的一个容器类,用于更优雅地处理可能为 null
的值。它可以明确表示”值可能不存在”的情况,避免 NullPointerException
。
1. 创建 Optional 对象
创建包含值的 Optional
1
| Optional<String> optional = Optional.of("value");
|
创建可能为空的 Optional
1
| Optional<String> optional = Optional.ofNullable(getStringThatMightBeNull());
|
创建空 Optional
1
| Optional<String> emptyOptional = Optional.empty();
|
2. 检查值是否存在
检查是否有值
1 2 3
| if (optional.isPresent()) { }
|
Java 11 简洁写法
1
| optional.ifPresent(value -> System.out.println("Found value: " + value));
|
3. 获取值
不安全获取(可能抛异常)
1
| String value = optional.get();
|
安全获取 - 提供默认值
1 2
| String value = optional.orElse("default"); String value = optional.orElseGet(() -> getDefaultValue());
|
安全获取 - 抛自定义异常
1
| String value = optional.orElseThrow(() -> new CustomException("Value not found"));
|
4. 链式操作
值转换 (map)
1
| Optional<String> upperCase = optional.map(String::toUpperCase);
|
扁平化转换 (flatMap)
1
| Optional<Double> result = optional.flatMap(this::parseToDouble);
|
过滤 (filter)
1
| Optional<String> filtered = optional.filter(s -> s.length() > 3);
|
5. 组合使用示例
1 2 3 4
| Optional.ofNullable(user) .map(User::getAddress) .map(Address::getStreet) .ifPresent(street -> System.out.println("Street: " + street));
|
6. 实际应用场景
替代 null 检查
1 2 3 4 5 6 7 8 9
| if (user != null && user.getAddress() != null) { }
Optional.ofNullable(user) .map(User::getAddress) .ifPresent(address -> { });
|
从集合中查找元素
1 2 3 4 5 6 7 8 9
| List<User> users = ...; Optional<User> user = users.stream() .filter(u -> u.getId().equals(id)) .findFirst();
user.ifPresentOrElse( u -> System.out.println("Found: " + u), () -> System.out.println("User not found") );
|
7. 注意事项
不要滥用 Optional:
- 不要作为方法参数(会使API复杂化)
- 不要用于类字段(设计问题)
- 集合应返回空集合而非
Optional<List>
性能考虑:
- 创建 Optional 对象有轻微开销
- 在性能关键代码中谨慎使用
不要这样用:
1 2 3 4 5
| if (optional.isPresent()) { return optional.get(); } else { return null; }
|
应该用 optional.orElse(null)
Optional
的正确使用可以使代码更清晰、更安全,减少 NullPointerException
的风险。