The example below shows a class (Club) that contains a collection of an abstract class (Member). I\'m confused as to whether I need a TypeAdapter or JsonDeserializer to make
Ok, real working example (I'm pretty sure this time).
The Club
package gson.test;
import java.util.ArrayList;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class Club {
public static void main(String[] args) {
// Setup a Club with 2 members
Club myClub = new Club();
myClub.addMember(new Silver("Jack"));
myClub.addMember(new Gold("Jill"));
myClub.addMember(new Silver("Mike"));
// Get the GSON Object and register Type Adapter
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(Member.class, new MemberDeserializer());
builder.registerTypeAdapter(Member.class, new MemberSerializer());
builder.setPrettyPrinting();
Gson gson = builder.create();
// Serialize Club to JSON
String myJsonClub = gson.toJson(myClub);
// De-Serialize to Club
Club myNewClub = gson.fromJson(myJsonClub, Club.class);
System.out.println(myClub.equals(myNewClub) ? "Cloned!" : "Failed");
System.out.println(gson.toJson(myNewClub));
}
private String title = "MyClub";
private ArrayList members = new ArrayList();
public boolean equals(Object club) {
Club that = (Club) club;
if (!this.title.equals(that.title)) return false;
for (int i=0; i
The Member Abstract Class
package gson.test;
public abstract class Member {
private String clsname = this.getClass().getName() ;
private int type;
private String name = "unknown";
public Member() { }
public Member(String theName) {this.name = theName;}
public int getType() { return type; }
public void setType(int type) { this.type = type; }
public boolean equals(Object member) {
Member that = (Member) member;
return this.name.equals(that.name);
}
}
The Concrete Sub-Classes Silver and Gold
package gson.test;
public class Silver extends Member {
private String silverData = "SomeSilverData";
public Silver() {
super();
this.setType(1);
}
public Silver(String theName) {
super(theName);
this.setType(1);
}
public boolean equals(Object that) {
Silver silver = (Silver)that;
return (super.equals(that) && this.silverData.equals(silver.silverData));
}
}
package gson.test;
public class Gold extends Member {
private String goldData = "SomeGoldData";
private String extraData = "Extra Gold Data";
public Gold() {
super();
this.setType(2);
}
public Gold(String theName) {
super(theName);
this.setType(2);
}
public boolean equals(Gold that) {
Gold gold = (Gold) that;
return (super.equals(that) && this.goldData.equals(gold.goldData));
}
}
The Custom Member Serailizer
package gson.test;
import java.lang.reflect.Type;
import com.google.gson.JsonElement;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
public class MemberSerializer implements JsonSerializer {
public JsonElement serialize(Member src, Type member, JsonSerializationContext context) {
switch (src.getType()) {
case 1: return context.serialize((Silver)src);
case 2: return context.serialize((Gold)src);
default: return null;
}
}
}
The custom Deserializer
package gson.test;
import java.lang.reflect.Type;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
public class MemberDeserializer implements JsonDeserializer {
@Override
public Member deserialize(JsonElement json, Type member, JsonDeserializationContext context) {
int myType = json.getAsJsonObject().get("type").getAsInt();
switch (myType) {
case 1: return context.deserialize(json, Silver.class);
case 2: return context.deserialize(json, Gold.class);
default: return null;
}
}
}
And... the output
Cloned!
{
"title": "MyClub",
"members": [
{
"silverData": "SomeSilverData",
"clsname": "gson.test.Silver",
"type": 1,
"name": "Jack"
},
{
"goldData": "SomeGoldData",
"extraData": "Extra Gold Data",
"clsname": "gson.test.Gold",
"type": 2,
"name": "Jill"
},
{
"silverData": "SomeSilverData",
"clsname": "gson.test.Silver",
"type": 1,
"name": "Mike"
}
]
}
I should note that my real use-case is one where performance should not be an issue, I'm loading a cache of objects from jSon text files so the frequency with this code is executed makes performance much less important than maintainability.