如何使用Lombok和Gson序列化抽象Getter方法?
解决Gson序列化时调用重写后的Getter方法返回常量值的问题
核心问题
原代码中,子类重写的getAbstractVariable()方法返回常量,但Gson序列化时未输出该字段,原因是父类同时定义了abstractVariable私有字段和抽象Getter方法,导致Gson的默认序列化逻辑无法正确关联到子类的重写方法;另外未赋值的concreteVariable因Gson默认忽略null值,也未出现在结果中。
类层面解决方案
方案1:移除父类中冗余的abstractVariable字段
子类重写的Getter方法直接返回常量,完全不需要父类的对应字段,移除后Gson会自动通过子类的Getter识别并序列化字段:
import lombok.Data; import com.google.gson.Gson; import java.io.Serializable; abstract class AbstractClass implements Serializable { // 移除冗余的abstractVariable字段 public abstract String getAbstractVariable(); } @Data class ConcreteClass extends AbstractClass implements Serializable { private String concreteVariable; @Override public String getAbstractVariable() { return "Constant Value"; } } public class SerializationTest { public static void main(String[] args) { Gson gson = new Gson(); ConcreteClass obj = new ConcreteClass(); obj.setConcreteVariable("test-value"); // 给字段赋值,避免Gson忽略null System.out.println("ConcreteClass=" + gson.toJson(obj)); // 输出:ConcreteClass={"concreteVariable":"test-value","abstractVariable":"Constant Value"} } }
方案2:保留父类字段,通过注解关联Getter方法
如果必须保留父类的abstractVariable字段,可通过Gson的@SerializedName注解强制关联子类的重写Getter:
方式A:在父类字段上配置
import lombok.Data; import lombok.Getter; import lombok.Setter; import com.google.gson.Gson; import com.google.gson.annotations.SerializedName; import java.io.Serializable; abstract class AbstractClass implements Serializable { @Setter @Getter(AccessLevel.NONE) // 禁止Lombok生成Getter,避免与抽象方法冲突 @SerializedName("abstractVariable") // 指定序列化字段名 private String abstractVariable; public abstract String getAbstractVariable(); } @Data class ConcreteClass extends AbstractClass implements Serializable { private String concreteVariable; @Override public String getAbstractVariable() { return "Constant Value"; } } public class SerializationTest { public static void main(String[] args) { Gson gson = new Gson(); ConcreteClass obj = new ConcreteClass(); obj.setConcreteVariable("test-value"); System.out.println("ConcreteClass=" + gson.toJson(obj)); // 输出:ConcreteClass={"concreteVariable":"test-value","abstractVariable":"Constant Value"} } }
方式B:在子类重写的Getter上配置
import lombok.Data; import lombok.Getter; import lombok.Setter; import com.google.gson.Gson; import com.google.gson.annotations.SerializedName; import java.io.Serializable; abstract class AbstractClass implements Serializable { @Setter @Getter private String abstractVariable; public abstract String getAbstractVariable(); } @Data class ConcreteClass extends AbstractClass implements Serializable { private String concreteVariable; @Override @SerializedName("abstractVariable") // 标记该方法对应序列化字段 public String getAbstractVariable() { return "Constant Value"; } } public class SerializationTest { public static void main(String[] args) { Gson gson = new Gson(); ConcreteClass obj = new ConcreteClass(); obj.setConcreteVariable("test-value"); System.out.println("ConcreteClass=" + gson.toJson(obj)); // 输出:ConcreteClass={"concreteVariable":"test-value","abstractVariable":"Constant Value"} } }
关键说明
- Gson默认优先访问字段而非Getter,但私有字段无法跨类访问时,会尝试匹配Getter方法;
- 原代码中父类的字段与子类Getter无关,导致Gson无法正确映射;
- Gson默认不序列化null值字段,因此需给
concreteVariable赋值才能在结果中看到。
内容的提问来源于stack exchange,提问作者Larvis
相关产品推荐
相关产品推荐

