子类继承父类后无法设置父类字段?原因及解决办法
问题原因与解决方案
原因分析
- Lombok @Data的默认行为限制:@Data注解会自动生成toString、equals、hashCode等方法,但默认只处理当前类的字段,不会包含父类的继承字段。所以当你打印ClassB对象时,toString输出里不会显示created_at的值,看起来像是没设置成功,但实际上字段值已经被set方法赋值了。
- 序列化工具的配置问题:如果是将对象转为JSON时看不到created_at,多数序列化工具(如Jackson)默认不会序列化父类的私有字段,导致输出结果中缺失该字段。
解决方法
方法1:让Lombok生成包含父类字段的toString/equals/hashCode
在ClassB上补充@ToString(callSuper = true)和@EqualsAndHashCode(callSuper = true)注解,显式开启父类字段的处理:
@Data @AllArgsConstructor @NoArgsConstructor @ToString(callSuper = true) @EqualsAndHashCode(callSuper = true) public class ClassB extends ClassA { private Boolean yesNo; private Commit commit; }
修改后,调用toString打印ClassB对象时,就能看到父类的created_at字段值了。
方法2:确保父类字段可被序列化(JSON场景)
如果是转JSON时缺失字段,在父类的created_at字段上添加@JsonProperty注解,让序列化工具识别并输出该字段:
@Data @AllArgsConstructor @NoArgsConstructor public class ClassA { private Integer id; @JsonProperty private String created_at; }
或者配置序列化工具(以Jackson为例),使其能访问父类私有字段:
ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
方法3:手动扩展子类构造函数(可选)
如果需要在实例化ClassB时直接初始化父类字段,可以手动编写包含父类参数的构造函数,替代Lombok自动生成的全参构造:
@Data @NoArgsConstructor public class ClassB extends ClassA { private Boolean yesNo; private Commit commit; public ClassB(Integer id, String created_at, Boolean yesNo, Commit commit) { super(id, created_at); this.yesNo = yesNo; this.commit = commit; } }
内容的提问来源于stack exchange,提问作者one-hand-octopus
相关产品推荐
相关产品推荐

