我有这样的课:
public class Barn {
String type;
Animal animal;
}
public class Horse extends Animal {
}
public class Cow extends Animal {
}
我想序列化它们的列表:
List<Barn> barns = new ArrayList<Barn>();
Barn barn1 = new Barn();
barn1.setType("horse");
barn1.setAnimal(new Horse());
barns.add(barn1);
Barn barn2 = new Barn();
barn2.setType("cow");
barn2.setAnimal(new Cow());
barns.add(barn2);
...
Group<Barn> barns = gson.fromJson(serialized);
当我序列化时,Animal 属性的类型信息将丢失。有没有办法以某种方式安装解析器监听器,以便在遇到列表中的每个元素时提供正确的类来反序列化?这就是手动提供描述类类型的字符串背后的想法。
谢谢
最佳答案
在 Gson 项目代码库中是 the RuntimeTypeAdapter ,据报道它适用于多态序列化和反序列化。我想我还没有尝试过使用它。见 http://code.google.com/p/google-gson/issues/detail?id=231了解更多信息。请注意,它尚未包含在任何 Gson 版本中。
如果使用它不能满足您的需求,则需要自定义反序列化处理。以下是一种这样的方法,假设您要使用演示的 JSON 结构。 (如果 JSON 结构可能不同,我会采取一些不同的方法。)
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.reflect.TypeToken;
public class App
{
public static void main(String[] args)
{
Barn[] barns = {new Barn(), new Barn()};
barns[0].type = "horse";
barns[0].animal = new Horse();
barns[1].type = "cow";
barns[1].animal = new Cow();
String json = new Gson().toJson(barns);
// [{"type":"horse","animal":{}},{"type":"cow","animal":{}}]
BarnDeserializer deserializer = new BarnDeserializer("type");
deserializer.registerBarnType("horse", Horse.class);
deserializer.registerBarnType("cow", Cow.class);
Gson gson = new GsonBuilder().registerTypeAdapter(Barn.class, deserializer).create();
List<Barn> barns2= gson.fromJson(json, new TypeToken<List<Barn>>(){}.getType());
for (Barn barn : barns2)
{
System.out.println(barn.animal.getClass());
}
}
}
class BarnDeserializer implements JsonDeserializer<Barn>
{
String barnTypeElementName;
Gson gson;
Map<String, Class<? extends Animal>> barnTypeRegistry;
BarnDeserializer(String barnTypeElementName)
{
this.barnTypeElementName = barnTypeElementName;
gson = new Gson();
barnTypeRegistry = new HashMap<>(); // Java 7 required for this syntax.
}
void registerBarnType(String barnTypeName, Class<? extends Animal> animalType)
{
barnTypeRegistry.put(barnTypeName, animalType);
}
@Override
public Barn deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException
{
JsonObject barnObject = json.getAsJsonObject();
JsonElement animalTypeElement = barnObject.get(barnTypeElementName);
Barn barn = new Barn();
barn.type = animalTypeElement.getAsString();
Class<? extends Animal> animalType = barnTypeRegistry.get(barn.type);
barn.animal = gson.fromJson(barnObject.get("animal"), animalType);
return barn;
}
}
class Barn {String type; Animal animal;}
class Animal {}
class Horse extends Animal {}
class Cow extends Animal {}
关于java - 如何使用多态处理反序列化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15736654/