You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Lombok生成接收父类实例的子类构造函数以实现字段拷贝?

用Lombok实现从父类实例构造子类实例

当然可以实现你要的功能!不过Lombok本身并没有提供专门的注解来直接生成“接收父类实例并拷贝字段”的子类构造函数,但我们可以结合它的现有注解+少量自定义代码,完美达成类似C++拷贝构造的效果——不管是浅拷贝还是后续要扩展深拷贝都能搞定。

第一步:先处理父类,确保字段可访问

首先得让子类能拿到父类的字段值,最省心的方式是用Lombok的@Data注解给父类生成getter/setter(或者你也可以把父类字段设为protected,不过用@Data更简洁):

import lombok.Data;

@Data
public class Parent {
    private String name;
    private int age;
    // 你定义的其他字段...
}

第二步:子类的两种实现方式

方式1:自定义构造函数+手动/工具类拷贝字段

这是最直接的方式,写一个接收Parent实例的构造函数,然后把父类的字段拷贝过来。如果父类字段不多,手动调用setter就行;字段多的话,用BeanUtils类(Spring或Apache Commons的都可以)一键拷贝,省得写一堆重复代码:

import lombok.Data;
import lombok.NoArgsConstructor;
// 如果用Spring的BeanUtils就加这个导入,Apache的类似
import org.springframework.beans.BeanUtils;

@Data
@NoArgsConstructor // 可选,生成无参构造
public class Child extends Parent {
    // 子类自己的字段
    private String childSpecificField;

    // 核心构造函数:接收父类实例并拷贝字段
    public Child(Parent parent) {
        // 方式A:手动拷贝(字段少的时候用)
        // this.setName(parent.getName());
        // this.setAge(parent.getAge());

        // 方式B:用BeanUtils一键拷贝(字段多的时候更高效,浅拷贝)
        BeanUtils.copyProperties(parent, this);
    }

    // 重载构造:同时接收父类实例和子类自己的字段
    public Child(Parent parent, String childSpecificField) {
        this(parent); // 先拷贝父类字段
        this.childSpecificField = childSpecificField;
    }
}

用的时候就这么写:

Parent parent = new Parent();
parent.setName("Alice");
parent.setAge(30);

// 从父类实例构造子类
Child child = new Child(parent);
// 或者带上子类自己的字段
Child childWithField = new Child(parent, "childValue");

方式2:用@Builder实现更优雅的构建

如果你喜欢用Builder模式,也可以结合Lombok的@Builder注解,写个静态方法来从父类实例构建子类,代码更优雅:

import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;

@Data
@EqualsAndHashCode(callSuper = true) // 让equals/hashCode包含父类字段
public class Child extends Parent {
    private String childSpecificField;

    // 用@Builder生成Builder,注意要显式调用父类构造
    @Builder
    public Child(String name, int age, String childSpecificField) {
        super(name, age);
        this.childSpecificField = childSpecificField;
    }

    // 静态方法:从Parent实例构建Child
    public static Child fromParent(Parent parent) {
        return Child.builder()
                .name(parent.getName())
                .age(parent.getAge())
                // 子类字段可以留空或者设默认值
                .build();
    }

    // 重载静态方法:支持传入子类字段
    public static Child fromParent(Parent parent, String childSpecificField) {
        return Child.builder()
                .name(parent.getName())
                .age(parent.getAge())
                .childSpecificField(childSpecificField)
                .build();
    }
}

调用的时候就更清爽了:

Parent parent = new Parent();
parent.setName("Bob");
parent.setAge(25);

Child child = Child.fromParent(parent);
Child childWithField = Child.fromParent(parent, "customChildField");

注意事项

  • 上面的实现都是浅拷贝,刚好符合你现在的需求;如果后续要深拷贝,只需要把BeanUtils换成深拷贝工具,或者手动处理引用类型字段就行。
  • 要是父类用了@NonNull之类的Lombok注解,记得在构造函数或Builder里也要对应处理,避免空指针。

内容的提问来源于stack exchange,提问作者abir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:12:29