Java gson的多态性

我在使用Gson反序列化json字符串时遇到问题。我收到一系列命令。该命令可以是start,stop或其他类型的命令。我自然具有多态性,并且start / stop命令从command继承。

如何使用gson将其序列化回正确的命令对象?

似乎我只获得基本类型,即声明的类型,而从未获得运行时类型。

回答:

根据我的研究以及使用gson-2.0时,你确实不想使用registerTypeHierarchyAdapter方法,而是更平凡的registerTypeAdapter。而且,你当然不需要为派生类做instanceofs或编写适配器:只为基类或接口提供一个适配器,当然,你对派生类的默认序列化感到满意。无论如何,这是代码(删除了打包和导入)(也可以在github中找到):

基类(在我的情况下为接口):

public interface IAnimal { public String sound(); }

这两个派生类Cat:

public class Cat implements IAnimal {

public String name;

public Cat(String name) {

super();

this.name = name;

}

@Override

public String sound() {

return name + " : \"meaow\"";

};

}

And Dog:

public class Dog implements IAnimal {

public String name;

public int ferocity;

public Dog(String name, int ferocity) {

super();

this.name = name;

this.ferocity = ferocity;

}

@Override

public String sound() {

return name + " : \"bark\" (ferocity level:" + ferocity + ")";

}

}

IAnimalAdapter:

public class IAnimalAdapter implements JsonSerializer<IAnimal>, JsonDeserializer<IAnimal>{

private static final String CLASSNAME = "CLASSNAME";

private static final String INSTANCE = "INSTANCE";

@Override

public JsonElement serialize(IAnimal src, Type typeOfSrc,

JsonSerializationContext context) {

JsonObject retValue = new JsonObject();

String className = src.getClass().getName();

retValue.addProperty(CLASSNAME, className);

JsonElement elem = context.serialize(src);

retValue.add(INSTANCE, elem);

return retValue;

}

@Override

public IAnimal deserialize(JsonElement json, Type typeOfT,

JsonDeserializationContext context) throws JsonParseException {

JsonObject jsonObject = json.getAsJsonObject();

JsonPrimitive prim = (JsonPrimitive) jsonObject.get(CLASSNAME);

String className = prim.getAsString();

Class<?> klass = null;

try {

klass = Class.forName(className);

} catch (ClassNotFoundException e) {

e.printStackTrace();

throw new JsonParseException(e.getMessage());

}

return context.deserialize(jsonObject.get(INSTANCE), klass);

}

}

和测试类:

public class Test {

public static void main(String[] args) {

IAnimal animals[] = new IAnimal[]{new Cat("Kitty"), new Dog("Brutus", 5)};

Gson gsonExt = null;

{

GsonBuilder builder = new GsonBuilder();

builder.registerTypeAdapter(IAnimal.class, new IAnimalAdapter());

gsonExt = builder.create();

}

for (IAnimal animal : animals) {

String animalJson = gsonExt.toJson(animal, IAnimal.class);

System.out.println("serialized with the custom serializer:" + animalJson);

IAnimal animal2 = gsonExt.fromJson(animalJson, IAnimal.class);

System.out.println(animal2.sound());

}

}

}

当运行Test :: main时,将得到以下输出:

serialized with the custom serializer:

{"CLASSNAME":"com.synelixis.caches.viz.json.playground.plainAdapter.Cat","INSTANCE":{"name":"Kitty"}}

Kitty : "meaow"

serialized with the custom serializer:

{"CLASSNAME":"com.synelixis.caches.viz.json.playground.plainAdapter.Dog","INSTANCE":{"name":"Brutus","ferocity":5}}

Brutus : "bark" (ferocity level:5)

我实际上也使用registerTypeHierarchyAdapter方法完成了上述操作,但这似乎需要实现自定义的DogAdapter和CatAdapter序列化器/反序列化器类,这在你想向Dog或Cat添加另一个字段时很难维护。

以上是 Java gson的多态性 的全部内容, 来源链接: utcz.com/qa/427119.html

回到顶部