Skip to content
DAILY QUOTE

“ ”

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、equalshashCodetoString,在JPA实体或包含双向关联的对象中需要谨慎使用。

4.Spring中的构造器注入

Spring组件推荐通过构造器注入必需依赖:

java
@Service
@RequiredArgsConstructor
public class UserService {
    private final UserMapper userMapper;
}

优点包括:

  • 依赖关系在构造器中明确可见
  • 必需依赖可以声明为final
  • 单元测试可以直接传入测试替身
  • 对象创建后不会出现必需依赖尚未注入的状态

final只表示字段引用初始化后不能重新赋值,不代表引用对象不可变,也不能单独保证线程安全。

@RequiredArgsConstructor适合仅对必需字段生成构造器。@AllArgsConstructor会包含所有字段,并非在Service中绝对不能使用,但普通状态字段被加入构造器通常说明类的职责需要重新检查。

5.使用边界

  • DTO和VO用于传输数据,可以按序列化框架要求选择无参构造器、带参构造器或Builder
  • 实体对象应通过构造器保证关键业务字段有效
  • Spring组件的构造器主要用于注入依赖,不应承载某次请求的业务数据