Gson support for polymorphic type handling is incomplete.
If possible, I highly recommend switching to Jackson, which handles the serialization problem in the original question flawlessly.
If Gson must be used, then custom serialization processing to handle such a data structure is necessary. Fortunately, the implementation of the custom serializer can be quite simple. For example:
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
public class GsonFoo
{
public static void main(String[] args)
{
C c = new C();
c.classes = new ArrayList<A>();
c.classes.add(new A(42));
c.classes.add(new B(8));
System.out.println(new Gson().toJson(c));
// output:
// {"classes":[{"stars":42},{"stars":-1}]}
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(A.class, new ASerializer());
Gson gson = gsonBuilder.create();
System.out.println(gson.toJson(c));
// output:
// {"classes":[{"stars":42},{"sunshines":8,"stars":-1}]}
}
}
class ASerializer implements JsonSerializer<A>
{
@Override
public JsonElement serialize(A src, Type typeOfSrc, JsonSerializationContext context)
{
Gson gson = new Gson();
return gson.toJsonTree(src);
}
}
class A
{
public int stars;
A(int s)
{
stars = s;
}
}
class B extends A
{
public int sunshines;
B(int s)
{
super(-1);
sunshines = s;
}
}
class C
{
public List<A> classes;
}