使用Optional优雅处理Null检查

传统方式与Optional对比

传统if-else方式

if(jsonNode != null) {
    JsonNode appIdNode = jsonNode.get("appId");
    if(appIdNode != null) {
        return appIdNode.asText();
    }
}
return "default";

使用Optional方式

return Optional.ofNullable(jsonNode)
    .map(x -> x.get("appId"))
    .map(JsonNode::asText)
    .orElse("default");

Optional核心用法详解

1. ofNullable()方法

// 安全创建Optional对象,允许传入null值
Optional.ofNullable(可能为null的对象)

// 错误示例 - 如果obj为null会抛出NPE
Optional.of(obj) 

2. map()方法链式调用

// 多级属性访问安全示例
String result = Optional.ofNullable(person)
    .map(Person::getAddress)
    .map(Address::getCity)
    .orElse("Unknown");

// 等价于:
String city = null;
if(person != null) {
    Address address = person.getAddress();
    if(address != null) {
        city = address.getCity();
    }
}
city = city != null ? city : "Unknown";

3. 常用终端操作

方法 描述
orElse(T) 为空时返回默认值
orElseGet(Supplier) 延迟计算默认值
orElseThrow() 为空时抛出异常
ifPresent(Consumer) 值存在时执行操作

最佳实践指南

  1. 避免在Optional内部调用可能NPE的方法

    // 错误 ❌
    Optional.ofNullable(jsonNode.get("appId"))
    
    // 正确 ✅
    Optional.ofNullable(jsonNode).map(x -> x.get("appId"))
    
  2. 多级属性访问模式

    // 安全的多级属性访问
    String displayName = Optional.ofNullable(application)
        .map(Application::getIcon)
        .map(Icon::getDisplayName)
        .orElse("default");
    
  3. 集合操作结合

    // 安全处理可能为null的集合
    List<String> names = Optional.ofNullable(users)
        .orElse(Collections.emptyList())
        .stream()
        .map(User::getName)
        .collect(Collectors.toList());
    
  4. 与Java 8 Stream结合

    // 安全处理嵌套集合
    List<String> emails = Optional.ofNullable(company)
        .map(Company::getDepartments)
        .orElse(Collections.emptyList())
        .stream()
        .flatMap(dept -> Optional.ofNullable(dept.getEmployees())
            .orElse(Collections.emptyList())
            .stream())
        .map(Employee::getEmail)
        .filter(Objects::nonNull)
        .collect(Collectors.toList());
    

性能考虑

  1. Optional会创建额外对象,在性能敏感场景慎用
  2. 简单null检查使用普通if判断可能更高效
  3. 对于高频调用的方法,考虑缓存Optional对象

常见错误

  1. 错误调用Optional.of()

    // 如果obj可能为null,应该用ofNullable
    Optional.of(obj.getSomething()); // 可能NPE
    
  2. 不必要的嵌套

    // 不推荐
    Optional.ofNullable(Optional.ofNullable(obj).orElse(defaultObj))
    
    // 推荐
    Optional.ofNullable(obj).orElse(defaultObj)
    
  3. 误用isPresent()

    // 不推荐
    if(optional.isPresent()) {
        return optional.get();
    }
    
    // 推荐
    return optional.orElse(defaultValue);
    

Optional为Java开发者提供了更优雅的null安全处理方式,合理使用可以使代码更简洁、更安全。

你可能感兴趣的:(java)