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