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

如何将继承类对象存入HashMap作为键?子类自定义属性无法保留

解决继承DFP Order类的自定义对象序列化丢失属性问题

我来帮你排查这个问题,之前也遇到过类似的继承类序列化丢失属性的情况,尤其是结合HashMap使用的时候,大概率是这几个原因导致的:

可能的原因

  • HashMap键的序列化限制:绝大多数JSON序列化库(比如Jackson、Gson)处理Map键时,默认会调用对象的toString()方法转成字符串,而不是完整序列化对象的所有属性。你的OrderForCalendar作为HashMap的键时,自定义的campaignCalendarStatus自然不会出现在最终JSON里。
  • 序列化框架未正确识别继承属性:如果单独序列化OrderForCalendar对象时也丢了属性,可能是框架没配置为包含父类属性,或者你的自定义属性没有getter方法、被@JsonIgnore之类的注解标记了。

针对性解决方案

1. 改用唯一ID作为HashMap的键(最推荐)

业务上如果允许的话,别用自定义对象当Map键,改用DFP Order类自带的唯一标识(比如ID字段)来存,既符合JSON序列化的常规玩法,还能避免自定义对象当键带来的哈希/相等性坑:

// 把键换成Order的ID,比如字符串类型
HashMap<String, ArrayList<LineItemForCalendar>> ordLineItemsMap = new HashMap<>();
// 存储时用OrderForCalendar的ID作为键
ordLineItemsMap.put(orderForCalendar.getId(), yourLineItemsList);

2. 配置序列化框架支持对象作为Map键(以Jackson为例)

如果必须保留自定义对象当键,就得给序列化框架做特殊配置,让它完整序列化键对象:
首先确保OrderForCalendar的campaignCalendarStatus有对应的getter方法,没被序列化忽略注解标记。然后自定义键的序列化器:

// 自定义键序列化器,把OrderForCalendar序列化为JSON字符串作为键
public class OrderForCalendarKeySerializer extends StdSerializer<OrderForCalendar> {
    public OrderForCalendarKeySerializer() {
        super(OrderForCalendar.class);
    }

    @Override
    public void serialize(OrderForCalendar value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        // 把对象转成JSON字符串作为Map的键
        String jsonStr = provider.getObjectMapper().writeValueAsString(value);
        gen.writeFieldName(jsonStr);
    }
}

// 在OrderForCalendar类上添加注解,指定用上面的序列化器
@JsonSerialize(using = OrderForCalendarKeySerializer.class)
public class OrderForCalendar extends Order {
    private String campaignCalendarStatus;

    // 一定要加getter,序列化框架需要通过它获取属性值
    public String getCampaignCalendarStatus() {
        return campaignCalendarStatus;
    }

    public void setCampaignCalendarStatus(String campaignCalendarStatus) {
        this.campaignCalendarStatus = campaignCalendarStatus;
    }
}

// 最后配置ObjectMapper并序列化
ObjectMapper mapper = new ObjectMapper();
String jsonResult = mapper.writeValueAsString(ordLineItemsMap);

3. 确保序列化框架支持继承属性

如果单独序列化OrderForCalendar对象时也丢属性,要检查框架对继承的处理:

  • 对于Jackson,默认会序列化父类的所有可访问属性(有getter的),如果DFP的Order类属性是私有的且没有getter,可以用@JsonAutoDetect开启字段级序列化:
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
public class OrderForCalendar extends Order {
    private String campaignCalendarStatus;
    // ... getter/setter
}

额外注意事项

  • 用自定义对象当Map键时,必须正确重写equals()和hashCode()方法,不然会出现找不到键、重复存储等奇怪问题。
  • 如果用方案2把对象转成JSON字符串当键,解析的时候需要额外处理,不如方案1用ID当键省心。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 04:28:34