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

如何在Java中实现JSON对象共享字段的无重复类定义?

解决方案:基于抽象父类的不可变实体设计

核心思路

通过抽象父类封装共享字段,子类继承父类并仅定义专属属性,结合Jackson的构造器注解实现无冗余的不可变类设计。由于反序列化时已明确指定目标类型,无需使用@JsonTypeInfo。

代码实现

1. 抽象父类(封装共享字段)

定义抽象类Pet,包含所有实体共享的name和age字段,通过带参构造器初始化,并添加@JsonProperty注解完成JSON字段映射:

import com.fasterxml.jackson.annotation.JsonProperty;

public abstract class Pet {
    private final String name;
    private final int age;

    protected Pet(@JsonProperty("name") String name, @JsonProperty("age") int age) {
        this.name = name;
        this.age = age;
    }

    // 不可变类仅提供只读访问方法
    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

2. 子类实现(仅定义专属属性)

每个子类继承Pet,仅声明自身专属的不可变字段,通过@JsonCreator标注构造器,确保Jackson能正确识别并完成反序列化:

Dog类示例

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

public class Dog extends Pet {
    private final String breed;

    @JsonCreator
    public Dog(
            @JsonProperty("name") String name,
            @JsonProperty("age") int age,
            @JsonProperty("breed") String breed
    ) {
        super(name, age);
        this.breed = breed;
    }

    public String getBreed() {
        return breed;
    }
}

Cat类示例

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

public class Cat extends Pet {
    private final boolean hasClaws;

    @JsonCreator
    public Cat(
            @JsonProperty("name") String name,
            @JsonProperty("age") int age,
            @JsonProperty("hasClaws") boolean hasClaws
    ) {
        super(name, age);
        this.hasClaws = hasClaws;
    }

    public boolean isHasClaws() {
        return hasClaws;
    }
}

Fish类示例

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

public class Fish extends Pet {
    private final String waterType;

    @JsonCreator
    public Fish(
            @JsonProperty("name") String name,
            @JsonProperty("age") int age,
            @JsonProperty("waterType") String waterType
    ) {
        super(name, age);
        this.waterType = waterType;
    }

    public String getWaterType() {
        return waterType;
    }
}

方案优势说明

  • 无冗余代码:共享字段和@JsonProperty仅在父类定义一次,子类无需重复编写。
  • 不可变性保证:所有字段均为final,无setter方法,构造器初始化所有属性,符合不可变类设计规范。
  • 无需类型注解:反序列化时明确指定目标类型(如mapper.readValue(input, Dog.class)),Jackson会直接调用对应子类的@JsonCreator构造器,自动完成父类与子类字段的映射,完全不需要@JsonTypeInfo。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 16:04:51