Optional可选值

Optional 可选值

Optional 至多包含一个非 null 值,用于在 API 类型上明确表达“结果可能缺失”。它改善的是契约,不是保证程序从此没有空指针。

创建

代码块JAVA · 3 行收起展开
Optional<String> present = Optional.of("Java");
Optional<String> empty = Optional.empty();
Optional<String> uncertain = Optional.ofNullable(maybeNull);
  • of(value) 不接受 null。
  • ofNullable(value) 把 null 转为空容器。
  • 不要返回 null 代替 Optional.empty()。

读取与兜底

方法行为
orElse(value)为空时返回值;参数总会先求值
orElseGet(supplier)为空时才调用 Supplier
orElseThrow()为空时抛异常
ifPresent(consumer)有值时执行
ifPresentOrElse(a, b)分别处理有值和无值
代码块JAVA · 2 行收起展开
User user = repository.findById(id)
        .orElseThrow(() -> new UserNotFoundException(id));

get() 在空容器上抛异常,通常应使用显式处理方法。

代码块JAVA · 2 行收起展开
User a = cached.orElse(loadFromDatabase());         // 总会查询
User b = cached.orElseGet(this::loadFromDatabase);  // 仅为空时查询

转换与筛选

代码块JAVA · 4 行收起展开
Optional<String> email = repository.findById(id)
        .filter(User::isActive)
        .map(User::getEmail)
        .filter(value -> !value.isBlank());

map 转换内部值;flatMap 用于映射函数本身返回 Optional;filter 在条件不满足时返回空。

Java 9 起可用 Optional.stream():

代码块JAVA · 4 行收起展开
List<User> users = ids.stream()
        .map(repository::findById)
        .flatMap(Optional::stream)
        .toList();

适用边界

推荐作为查询方法返回值:

代码块JAVA · 1 行收起展开
Optional<User> findById(long id);

通常不推荐:

  • 用作方法参数。
  • 用作实体或 DTO 字段。
  • 用作集合元素。
  • 返回 Optional<List>,空列表通常已经能表达没有元素。
  • 只为了 isPresent() 后马上 get()。

延伸阅读