Java构造器的作用
构造器用于在创建对象时建立有效的初始状态。构造器没有返回值,名称必须与类名一致。
1.无参构造器
无参构造器适合以下场景:
- 先创建对象,再通过Setter或字段绑定填充数据
- 框架通过反射实例化对象
- JavaBean规范要求提供无参构造器
不同框架的要求并不完全相同。部分ORM、序列化或代理机制需要无参构造器,Jackson等框架也支持通过带参构造器或工厂方法创建对象,因此不能笼统地认为所有框架都必须使用无参构造器。
如果类中没有声明任何构造器,Java编译器会生成默认无参构造器。一旦显式声明了其他构造器,默认无参构造器就不会生成。
Lombok可以使用:
java
@NoArgsConstructor
public class User {
}2.带参构造器
带参构造器可以在对象创建时一次性提供必要数据,避免对象处于不完整状态:
java
public class User {
private final Long id;
private String name;
public User(Long id, String name) {
this.id = id;
this.name = name;
}
}参数较多时,全参构造器容易出现参数顺序错误。可以根据对象用途选择静态工厂方法、Builder或拆分对象,而不是机械地给所有类添加@AllArgsConstructor。
3.实体类中的Lombok
常用注解包括:
@NoArgsConstructor:生成无参构造器@AllArgsConstructor:生成包含全部字段的构造器@RequiredArgsConstructor:生成包含final字段和标记为@NonNull字段的构造器@Builder:生成Builder API
是否使用这些注解取决于框架要求和对象设计。@Data会同时生成Getter、Setter、equals、hashCode和toString,在JPA实体或包含双向关联的对象中需要谨慎使用。
4.Spring中的构造器注入
Spring组件推荐通过构造器注入必需依赖:
java
@Service
@RequiredArgsConstructor
public class UserService {
private final UserMapper userMapper;
}优点包括:
- 依赖关系在构造器中明确可见
- 必需依赖可以声明为
final - 单元测试可以直接传入测试替身
- 对象创建后不会出现必需依赖尚未注入的状态
final只表示字段引用初始化后不能重新赋值,不代表引用对象不可变,也不能单独保证线程安全。
@RequiredArgsConstructor适合仅对必需字段生成构造器。@AllArgsConstructor会包含所有字段,并非在Service中绝对不能使用,但普通状态字段被加入构造器通常说明类的职责需要重新检查。
5.使用边界
- DTO和VO用于传输数据,可以按序列化框架要求选择无参构造器、带参构造器或Builder
- 实体对象应通过构造器保证关键业务字段有效
- Spring组件的构造器主要用于注入依赖,不应承载某次请求的业务数据