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

@RequiredArgsConstructor 和构造同时使用,注入会不会导致空指针

会,极有可能导致空指针异常。 如果你在同一个类上同时使用 @RequiredArgsConstructor 和显式编写的构造方法,并且处理不当,就会发生空指针。

详细解释

  1. @RequiredArgsConstructor 的作用
    Lombok 的 @RequiredArgsConstructor 会在编译时为类生成一个构造方法。这个构造方法会为所有被 @NonNull 注解标记的、未初始化的 final 字段生成一个参数。

java
@Service
@RequiredArgsConstructor
public class MyService {

private final SomeRepository repository; // final 字段,会被包含
private AnotherService anotherService;   // 非final,不会被包含// Lombok 会自动生成这个构造方法:
// public MyService(SomeRepository repository) {
//     this.repository = repository;
// }

}
当 Spring 容器创建这个 Bean 时,它会自动寻找这个构造方法并使用它来注入 SomeRepository 依赖。这是构造器注入,也是 Spring 官方推荐的方式。

  1. 当你同时编写构造方法时会发生什么?
    Java 的规则是:如果你显式地定义了任何构造方法,编译器就不会再为你生成默认的无参构造方法。

Lombok 也遵循类似的规则:如果你显式定义了任何构造方法,Lombok 的 @RequiredArgsConstructor 就不会生效(除非你使用了 @RequiredArgsConstructor(onConstructor = …) 等特殊配置,但这是另一个话题)。

错误示例:

java
@Service
@RequiredArgsConstructor // 这行注解实际上失效了!
public class MyService {

private final SomeRepository repository;// 程序员自己写的构造方法
public MyService() {System.out.println("MyService created");// 问题:repository 字段没有被赋值!// this.repository = null;
}public void doSomething() {repository.findById(1L); // 这里会抛出 NullPointerException!
}

}
发生了什么?

你添加了 @RequiredArgsConstructor,期望 Lombok 生成 MyService(SomeRepository repository)。

但是,你又显式地编写了一个无参构造方法 MyService()。

Lombok 检测到你已经有了一个构造方法,因此它不会再生成它自己的构造方法。

Spring 在创建 MyService Bean 时,发现没有带参数的构造方法,于是选择了你写的无参构造方法。

通过无参构造方法创建对象后,final 字段 repository 没有被初始化,其值为 null。

当你调用 repository 的任何方法时,自然就会抛出 NullPointerException。

  1. 如何正确使用?
    最佳实践(二选一):

方案一:纯粹依赖 Lombok(推荐)
不要自己写构造方法,完全让 @RequiredArgsConstructor 来负责生成。这是最简洁、最不容易出错的方式。

java
@Service
@RequiredArgsConstructor
public class MyService {

private final SomeRepository repository;
// 其他业务逻辑...
// 不要写任何构造方法!

}
方案二:完全自己管理构造方法(适用于需要额外初始化逻辑时)
如果你需要在构造方法里做一些额外的初始化工作,那就不要使用 @RequiredArgsConstructor,自己完整地编写构造方法,并用 @Autowired 注解(在 Spring 4.3 之后,如果只有一个构造方法,可省略 @Autowired)。

java
@Service
public class MyService {

private final SomeRepository repository;// 自己编写构造方法,并完成注入和初始化
public MyService(SomeRepository repository) {this.repository = repository; // Spring 会从这里注入// ... 这里可以写其他初始化代码System.out.println("MyService created with repository: " + repository);
}

}
总结
场景 结果 建议
只用 @RequiredArgsConstructor 正常。Lombok 生成构造方法,Spring 用它来注入。 推荐
@RequiredArgsConstructor + 自定义无参构造 异常。Lombok 不生成构造方法,Spring 使用无参构造,导致依赖为 null。 禁止
@RequiredArgsConstructor + 自定义带参构造 混乱且危险。行为不可预测,极易出错。 禁止
只用自定义构造方法 正常。清晰明确,可添加自定义逻辑。 可选
结论:永远不要在同一个类上混合使用 @RequiredArgsConstructor 和显式编写的构造方法。 选择其中一种方式并坚持使用。对于大多数只需要注入依赖的场景,直接使用 @RequiredArgsConstructor 是最佳选择。

http://www.dtcms.com/a/356083.html

相关文章:

  • Dify 中的 Signal Killed 问题排查指南
  • 强化学习入门专栏目录
  • 2002-2020年全国投入产出表数据
  • 【C++八股文】操作系统篇
  • C语言 部分内存相关的库函数
  • 广东省省考备考(第八十九天8.28)——判断推理(听课后强化训练)
  • 事务的五大状态
  • QT LInux 开发中一些常用的方法
  • CVPR小模型创新点深度分析:小VLM化身精准向导,大模型多模态推理效率全面加速,性能突破不再依赖算力堆叠
  • 8.28作业
  • Android 编写高斯模糊功能
  • Github上传READ.md后出现不识别换行符的问题
  • Shell编程入门到实战:从基础语法到自动化脚本
  • 网络是怎样连接的,笔记整理
  • C语言知识点补充(链表和队列)
  • 8.变量和数据类型
  • 浏览器访问 ASP.NET Core wwwroot 目录下静态资源的底层实现
  • 多线程 线程池 并发
  • 机器视觉学习-day08-图像缩放
  • MBA/EMBA毕业论文写作总结
  • 第20章|轻松实现远程控制
  • NumPy 2.x 完全指南【三十二】通用函数(ufunc)之数学运算函数
  • 面试tips--JVM(1)--对象分配内存的方式TLAB
  • CTFshow系列——命令执行web61-68
  • C++之多态篇
  • 君正T31学习(四)- MT7682+VLC出图
  • 【python】python进阶——as关键字
  • 程序代码篇---类
  • SpringCloud Alibaba Nacos 注册中心/配置中心
  • SpringBoot 配置文件在运维开发中的应用