Optional类的解析与使用

一个可以用来存储空值非空值的容器,旨在优雅地处理可能为 null 的值 ,从而减少 NullPointerException 的发生,提高代码的可读性和健壮性。

封包行为

封包行为 ”指的是将一个值封装进 Optional 容器中,返回值为Option<T>使其成为一个可显式表达“值可能存在或缺失”的对象。这种封装是使用 Optional 的第一步,也是后续链式调用和解包操作的基础。

Optional.of(T value)

将一个非空值封装为 Optional

  • 如果 value != null,返回一个包含该值的 Optional

  • 如果 value == null,抛出 NullPointerException

  • 使用场景

    • 确保值一定不null 时使用。

Optional.ofNullable(T value)

将一个可能为 null 的值封装为 Optional

  • 如果 value != null,返回一个包含该值的 Optional
  • 如果 value == null,返回一个空的 Optional(即 Optional.empty())。
  • 使用场景
    • 可能null,需要安全封装时使用。

解包行为

Optional 的核心设计目标之一是显式处理值是否存在 ,因此它提供了多种“解包”方法来安全地获取内部值或处理缺失值的情况 。以下是 Optional 中所有用于解包的常见方法及其使用场景和区别:

get

T get()

直接获取值(如果存在)。

  • 如果值存在,返回值。不存在(即 Optional 为空),抛出 NoSuchElementException
  • 不推荐直接使用 ,因为容易抛出异常。
Optional<User> optionalUser = Optional.of(new User("Alice"));
User user = optionalUser.get(); // 返回 Alice

orElseThrow

T orElseThrow(Supplier<? extends X> exceptionSupplier)

如果值存在,返回值;否则抛出指定异常。

  • 可以自定义异常类型和信息,适合业务逻辑中主动抛异常(推荐)
User user = Optional.ofNullable(findUserById(123))
                     .orElseThrow(() -> new RuntimeException("用户不存在"));

orElse

T orElse(T other)

如果值存在,返回值;否则返回默认值 other

  • 默认值简单且计算成本低时使用。(立刻计算)
String name = Optional.ofNullable(user.getName()).orElse("Unknown");

orElseGet

T orElseGet(Supplier<? extends T> supplier)

如果值存在,返回值;否则调用 supplier 生成默认值。

  • 默认值计算成本较高(如读取文件、调用数据库等),调用 supplier 延迟生成默认值(惰性求值 )。
String name = Optional.ofNullable(user.getName())
                       .orElseGet(() -> loadDefaultNameFromDB());

ifPresent

void ifPresent(Consumer<? super T> consumer)

如果值存在,执行 consumer 操作,如果值不存在,不做任何操作。

  • 值存在时需要执行某些副作用(如赋值、打印日志等)。
Optional.ofNullable(user).ifPresent(u -> System.out.println("User found: " + u.getName()));

使用场景

场景一:对象存在性检查 + 条件操作

当对象存在时,执行某个操作(如赋值、打印等),否则忽略。

Optional.ofNullable(user).ifPresent(u->u.setName("aciu"));

场景二:条件过滤 + 异常抛出

对对象进行条件验证,若不满足条件则抛出异常。

return Optional.ofNullable(user)
    	.filter(s -> !isEmpty(s.getName()))
    	.orElseThrow(() -> new BizException("查询不到该记录"));

场景三:链式属性访问 + 安全获取嵌套值

从多级嵌套对象中安全获取属性值,避免中间对象为 null 导致空指针。

Optional.ofNullable(comp)
    .map(Competition::getResult)
    .map(CompResult::getChampion)
    .map(User::getName)
    .orElseThrow(() -> new IllegalArgumentException(...));

场景四:配置解析 + 默认值处理

从配置或外部数据源获取值,若值缺失或转换失败则使用默认值。

int timeout = Optional.ofNullable(redisProperties.getTimeout())
    .map(x -> Long.valueOf(x.toMillis()).intValue())
    .orElse(10000);

不推荐场景

  • 不推荐作为类的字段(不可序列化、内存开销)。
  • 不推荐用于方法参数(应由调用者保证合法性)。
  • 高频调用的代码块(轻微性能开销)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值