Reputation: 51
Example classes:
public class A
{
String Name;
List<B> GenericsList;
//Getters & Setters & Constructors
}
public class B
{
String Title;
//Getters & Setters & Constructors
}
public class C extends B
{
String Something;
//Getters & Setters & Constructors
}
If i serialize an instance of class A like this:
List<B> bList = new ArrayList<>();
C bObj = new C("name", "something text");
bList.add(bObj);
A aObj = new A("name", bList);
String serialized = new Gson.toJson(aObj);
A deserializedA = new Gson.fromJson(serialized);
I lose the C subtype in the List. I know how to work around this if its just a List to serialize like this:
Gson gson = new Gson();
List<B> bList = new ArrayList<>();
Type bType = new TypeToken<List<B>>() {}.getType();
gson.toJson(bList, bType);
gson.fromJson(json, bType);
The problem is that my generics list is inside an object with other parameters. How do i do this?
Edit 1: Maybe i was not clear about the concrete problem.
When i serialize and deserialize the created A object above there is no error but instead of getting this: Object A: Name = "name" GenericsList = {Object C}
i get: Object A: Name = "name" GenericsList = {Object B}
i lose the subtype C detail.
Upvotes: 2
Views: 4859
Reputation: 51
Got it! Thanks for the tip Sotirios Delimanolis!
Had to create a custom implementation for the B class:
class BGsonAdapter implements JsonSerializer<B>, JsonDeserializer<B>
{
public JsonElement serialize(B bObj, Type typeOfSrc, JsonSerializationContext context)
{
JsonObject result = new JsonObject();
result.add("Title", context.serialize(B.getTitle(), String.class));
if (bObj instanceof C)
{
result.add("Something", context.serialize(((C)bObj).getSomething(), String.class));
}
return result;
}
public B deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
{
JsonObject object = json.getAsJsonObject();
B result = null;
if (object.has("Something"))
{
result = new C();
((C) result).setSomething((String)context.deserialize(object.get("Something"), String.class));
if (result == null)
{
result = new B();
}
result.setTitle(((String)context.deserialize(object.get("Title"), String.class)));
return result;
}
}
and use it like this:
Gson gson = new GsonBuilder()
.registerTypeHierarchyAdapter(B.class, new BGsonAdapter())
.setPrettyPrinting()
.create();
String serialized = gson.toJson(A);
A deserialized = (A)gson.fromJson(A);
Upvotes: 2