java 容器 Optional

在编程里,Optional 是一个「容器类」,核心作用是优雅解决空指针异常(NullPointerException),最常见于 Java 8 及以上版本,其他语言(如 Kotlin、Python)也有类似实现。
用大白话讲:它就像一个 “快递盒子”,里面可能装着你需要的对象(非空),也可能是空盒子(没东西)。通过它,你不用再写一堆 if (obj != null) 的判断,代码更简洁、更安全。

一、核心价值:解决什么痛点?

在没有 Optional 之前,我们判断对象是否为空要这么写:
java
 
运行
 
 
 
 
// 传统写法:繁琐且容易漏判
String name = getUser().getName();
if (name != null) {
    System.out.println(name.length());
} else {
    System.out.println("名称为空");
}
// 万一 getUser() 本身就是 null,这行直接抛空指针!
 
用 Optional 之后,代码变成这样:
java
 
运行
 
 
 
 
// Optional 写法:链式调用,优雅避空
Optional.ofNullable(getUser())
       .map(User::getName)  // 提取name属性
       .ifPresent(name -> System.out.println(name.length()));  // 有值才执行
 

二、Optional 常用方法(大白话解释)

方法 作用 实用场景
Optional.of(obj) 创建 Optional 对象,obj 不能为 null,否则直接抛异常 确定对象一定非空时用
Optional.ofNullable(obj) 创建 Optional 对象,obj 可以为 null 不确定对象是否为空时(最常用)
optional.isPresent() 判断容器里是否有值(返回 boolean) 类似传统的 obj != null
optional.ifPresent(fn) 有值时执行函数 fn,无值时啥也不做 替代 if (obj != null) 的逻辑
optional.get() 获取容器里的值,无值时抛异常 尽量少用!只有确定有值时才用
optional.orElse(defaultVal) 无值时返回默认值 兜底:没拿到对象就用默认值
optional.orElseGet(supplier) 无值时通过函数生成默认值(懒加载) 默认值创建成本高时用(比如查数据库)
optional.orElseThrow(exception) 无值时抛自定义异常 没拿到值需要主动报错时(比如接口参数校验)
optional.map(fn) 对容器里的值做转换,返回新的 Optional 提取对象的属性(如 getUser ().getName ())

三、典型用法示例

  1. 获取值 + 兜底默认值
java
 
运行
 
 
 
 
// 无值时返回 "匿名用户"
String userName = Optional.ofNullable(getUser())
                          .map(User::getName)
                          .orElse("匿名用户");
 
  1. 无值时抛自定义异常
java
 
运行
 
 
 
 
// 没拿到用户就抛参数异常
User user = Optional.ofNullable(getUserById(1))
                    .orElseThrow(() -> new IllegalArgumentException("用户不存在"));
 
  1. 多层级属性提取(避免嵌套判空)
java
 
运行
 
 
 
 
// 传统写法要判3次空:user != null → address != null → city != null
// Optional 写法:链式调用,一步到位
String city = Optional.ofNullable(user)
                      .map(User::getAddress)
                      .map(Address::getCity)
                      .orElse("未知城市");
 

四、使用注意事项

  1. 不要用 isPresent() + get() 替代传统判空,这等于脱裤子放屁:
    java
     
    运行
     
     
     
     
    // 反面教材!和 if (obj != null) 没区别
    if (optional.isPresent()) {
        optional.get();
    }
     
     
  2. Optional 不能序列化,别用来当类的成员变量或方法参数;
  3. 优先用 orElseGet 代替 orElse,前者是 “需要时才创建默认值”,后者是 “不管要不要都创建”,性能更好。

五、其他语言的类似实现

  • Kotlin:直接用 ? 空安全操作符(如 user?.name),比 Optional 更简洁;
  • Python:没有原生 Optional,但可以用 typing.Optional 做类型注解(如 Optional[str] 表示 str 或 None)。
posted @ 2025-12-29 16:11  高手大8  阅读(0)  评论(0)    收藏  举报