如何通过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
相关产品推荐
相关产品推荐

