Yes, I also came across this problem. It is not possible for gson to determine the actual class of the field value. It just tries to instantiate the class used to define the field. Needless to say, this is often not what we want. so if you said
class C { private A a; private A c; } class B extends A { }
then at runtime you
C c; ca = new B(); cc = new B();
after deserialization, what you get is
cagetClass()==A.class; cbgetClass()==A.class;
so you will need to specify the subclass explicitly. Here is a wrapper class that is handy for gson.
public class S<T> { private String objectClass; private String rawObjectRepresentation; // Gson needs no args constructor public S() { } public S(T obj) { objectClass = obj.getClass().getName(); rawObjectRepresentation = getGson().toJson(obj); } @SuppressWarnings("unchecked") public T extract() throws ClassNotFoundException { final Class<?> clazz = Class.forName(objectClass); return (T)getGson().fromJson(rawObjectRepresentation, clazz); } private Gson getGson() { return new GsonBuilder().create(); } @Override public String toString() { return "type:"+objectClass; } }
source share