当前位置: 首页 > news >正文

Java 避免空指针的方法及Optional最佳实践

【一】避免空指针的通用方法

✅ 1️⃣ 设计阶段:避免产生 null

  • 领域模型里避免「nullable」属性

  • 构造函数里要求非空

✅ 示例

public User(String name) {

   this.name = Objects.requireNonNull(name, "name must not be null");

}


✅ 2️⃣ 静态检查

  • 注解

    • @Nonnull, @Nullable

    • Checker Framework / ErrorProne / SpotBugs

✅ 示例

public String process(@Nonnull String input) { return input.trim(); }


✅ 3️⃣ 运行时保护

  • Objects.requireNonNull()


✅ 4️⃣ 语言级增强

  • Java 14+: 增强的 NPE 异常信息

    • 默认开启(Java 16+)

    • -XX:+ShowCodeDetailsInExceptionMessages

✅ 输出示例

Cannot invoke "Address.getCity()" because "person.getAddress()" is null


✅ 5️⃣ Null Object 模式

避免返回 null,用无害对象表示「空行为」

✅ 示例

class NullLogger implements Logger {

   public void log(String msg) { /* do nothing */ }

}


✅ 6️⃣ Optional

Java 8+ 的核心改进:明确表达「可能缺失」

✅ 语义

  • Optional 返回值 → 明确可为空

  • 避免调用者遗漏 null 检查

✅ 基本用法

Optional<User> findById(String id) {

   return Optional.ofNullable(repo.get(id));

}


【二】Optional 最佳实践

✅ ① 适用场景

✅ 用于方法返回值

  • 表示查询、解析、计算 可能没有结果

✅ 示例

Optional<User> findUserById(String id);


❌ ② 不推荐场景

❌ 参数

void setUser(Optional<User> user); // 不推荐

✅ 用

void setUser(@Nullable User user);


❌ 类字段

class User {

   Optional<Address> address; // 不推荐

}

✅ 用

class User {

   @Nullable Address address;

}

然后在 getter 中返回 Optional

public Optional<Address> getAddress() {

    return Optional.ofNullable(address);

}


❌ 集合

Optional<List<User>> getUsers(); // 不推荐

✅ 直接返回空集合

List<User> getUsers();


✅ ③ 创建 Optional

Optional.of(value) // value != null

Optional.ofNullable(value) // 允许 value 为 null

Optional.empty()


✅ ④ 消费值

optional.ifPresent(u -> sendEmail(u.getEmail()));


✅ ⑤ 默认值

String result = optional.orElse("default");

String lazy = optional.orElseGet(() -> computeDefault());


✅ ⑥ 抛异常

User user = optional.orElseThrow(() -> new NotFoundException());


✅ ⑦ 链式变换

Optional<Address> address = userOpt.map(User::getAddress); Optional<String> city = userOpt.map(User::getAddress).map(Address::getCity);


✅ ⑧ 过滤

optional.filter(u -> u.isActive())


✅ ⑨ Java 9+ 扩展

optional.or(() -> otherOptional);

optional.ifPresentOrElse( val -> process(val), () -> handleAbsent() );


✅ ⑩ 避免 get()

⚠️ 反模式

String s = optional.get(); // 潜在 NPE

✅ 推荐

optional.orElse(...) optional.orElseThrow(...)


总结

✅ 方法返回值 → Optional 表示「可无」
✅ 参数 → 不用 Optional,直接 @Nullable
✅ 字段 → 不用 Optional,用普通类型 + @Nullable
✅ 集合返回值 → 返回空集合,不要包 Optional
✅ 使用链式 map / flatMap / filter
✅ 消费时用 orElse / orElseThrow / ifPresent

http://www.xdnf.cn/news/1125469.html

相关文章:

  • 【Linux系统】命令行参数和环境变量
  • 【Java篇】IntelliJ IDEA 安装与基础配置指南
  • 网络安全职业指南:探索网络安全领域的各种角色
  • 蛋白质组学技术揭示超急性HIV-1感染的宿主反应机制
  • HR数字化转型:3大痛点解决方案与效率突破指南
  • 渭河SQL题库-- 来自渭河数据分析
  • 在 SymPy 中精确提取三角函数系数的深度分析
  • Spring Boot - Spring Boot 集成 MyBatis 分页实现 RowBounds
  • MySQL高级篇(二):深入理解数据库事务与MySQL锁机制
  • AutoGPT vs BabyAGI:自主任务执行框架对比与选型深度分析
  • 【PTA数据结构 | C语言版】二叉树层序序列化
  • TiD2025 | openKylin基础设施平台创新实践分享,构筑开源质量根基
  • ZYNQ千兆光通信实战:Tri Mode Ethernet MAC深度解析
  • 全面安装指南:在Linux、Windows和macOS上部署Apache Cassandra
  • 基于多智能体强化学习的医疗检索增强生成系统研究—MMOA-RAG架构设计与实现
  • wpf Canvas 动态增加右键菜单
  • Kafka与Flink打造流式数据采集方案:以二手房信息为例
  • 如何设计实现开发自助重启工具-01-设计篇
  • MIPI DSI(四) video 和 command 模式
  • npm install failed如何办?
  • GitHub 上 Star 数量前 8 的开源 Web 应用项目
  • 职业院校网络安全攻防对抗实训室解决方案
  • 微信小程序进度条cavans
  • 2025.7.15总结
  • docker拉取nacos镜像失败
  • GaussDB 数据库架构师修炼(四) 备份容量估算
  • AntV G6 基础元素详解(React版)
  • 邮件伪造漏洞
  • IOS 18下openURL 失效问题
  • 跨平台移动开发技术深度分析:uni-app、React Native与Flutter的迁移成本、性能、场景与前景