1 回答
TA贡献1784条经验 获得超8个赞
我真的不知道在没有手动或hacky的情况下使用gson执行此操作的方法。这太大了,无法作为评论发表,因此我将其留在这里作为答案,以帮助您解决问题。
首先,您会遇到堆栈溢出,因为您正在调用context.deserialize相同的参数,这些参数触发gson调用相同的反序列化器,它将再次调用context.deserialize,依此类推,直到堆栈溢出。
序列化时你会遇到同样的问题,因为你也只是在做context.serialize.
为避免这种情况,您需要避免gson递归调用序列化器/反序列化器的方法。这很容易通过创建另一个gson没有适配器的实例来实现:
public class PetAdapter
implements JsonSerializer<Pet>, JsonDeserializer<Pet> {
private final Gson gson = new Gson();
@Override
public Pet deserialize(JsonElement jsonElement, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
EntityType entityType = EntityType.valueOf(jsonElement.getAsJsonObject().get("entityType").getAsString());
switch (entityType) {
case IRON_GOLEM:
return gson.fromJson(jsonElement, EcoPet.class);
case WOLF:
return gson.fromJson(jsonElement, BoostPet.class);
case MAGMA_CUBE:
return gson.fromJson(jsonElement, CombatPet.class);
default:
throw new JsonParseException("Invalid PetType");
}
}
@Override
public JsonElement serialize(Pet src, Type typeOfSrc, JsonSerializationContext context) {
return gson.toJson(src);
}
}
这有效,但前提是您的Pet实现不依赖于其他自定义序列化器/反序列化器。所以你可以想象这很hacky。
另一种方法是手动反序列化。这意味着您必须通过 json 元素并读取属性,就像您正在阅读entityType和手动构建您的对象一样。
非常相似,我想(我没有检查这个),您可以首先context将每个宠物反序列化为一个Map对象,并让每个宠物实现一个静态方法,该方法从该地图创建特定宠物的实例。就像是:
public class IronGolem extends Pet {
public static IronGolem from(Map<String, Object> deserializedPet) {
// here check the map for each thing you need
return new IronGolem(/*pass in every attribute*/);
}
}
希望这可以帮助。
添加回答
举报