You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
First class support for polymorphism (subclasses!) #231
GSON always operates on the static type of an object. It has no mechanism to
operate on the object's runtime type.
It would be handy if GsonBuilder permitted a way to specify the known
subclasses of a type. Then at serialization/deserialization these fields could
be included:
public void testPolymorphism() {
Rectangle r = new Rectangle();
r.width = 5;
r.height = 7;
Circle c = new Circle();
c.radius = 3;
List<Shape> shapes = new ArrayList<Shape>();
shapes.add(r);
shapes.add(c);
Gson gson = new GsonBuilder()
.create();
String json = gson.toJson(shapes, new TypeToken<List<Shape>>() {}.getType());
assertEquals("[{\"width\":5,\"height\":7},{\"radius\":3}]", json);
}
static class Shape {}
static class Rectangle extends Shape {
int width;
int height;
}
static class Circle extends Shape {
int radius;
}
It would be extra awesome if it could use the set of fields in a stream to
infer the type to instantiate. In the example above, it could use that the
'radius' field as evidence that the runtime type should be a Circle. Or perhaps
this could be user-configured too, such as this:
new GsonBuilder()
.runtimeType(Shape.class, Circle.class, "radius")
.runtimeType(Shape.class, Rectangle.class, "width", "height")
.create();
Original issue reported on code.google.com by limpbizkit on 28 Aug 2010 at 6:00
I don't think so.
Guess I'll either have to write some generic converters or switch back to Jackson, as I rely on loads of Collections filled with abstract classes for a project...
Hey guys ,
I have a similar usecase as this
Class A{
// fields
}
Class B extends A{
// fields
}
Class C extends A{
// fields
}
Class D extends A{
// fields
}
Class Test extends A{
public List contents = new ArrayList(); // it may contain A, B, C etc.
private boolean isHeader = false;
private String myTestString = "test";
}
I am trying to serialize "contents " collection using gson libarary.
can someone tell me whats the solution for this. I found using RuntimeTypeAdaptorFactory would solve it but, I using gson 2..5, in that version I dont see this class.
Struck with this issues for a past three days. writing custom serializations code for my usecase runs for pages.kindly help. whats the work around that the current gson library is having.
Add pull request #1055 that shows a few issues regarding Collection. I would be glad about feedback.
My problem is that I need to deserialize Collections at runtime - thus I can't use the new TypeToken<List>() {}.getType() syntax. I only have a Class instance. Do I have to register some special type of Collection adapter or JsonDeserializer? I tried to add a deserializer but this wasn't possible because I lack needed types for fromJson calls.
private class RunTimeTypeCollectionAdapter implements JsonDeserializer<Collection> {
@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
public Collection deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context)
throws JsonParseException {
if (json == null) {
return null;
}
final TypeToken<?> typeToken = TypeToken.get(typeOfT);
try {
Class<?> collectionClass = typeToken.getRawType();
if (collectionClass == List.class) {
collectionClass = ArrayList.class;
} else if (collectionClass == Set.class) {
collectionClass = HashSet.class;
} else if (collectionClass == Map.class) {
collectionClass = HashMap.class;
}
final Collection collection = (Collection) Class.forName(collectionClass.getTypeName()).newInstance();
final Class<?> rawType = typeToken.getRawType();
if (json.isJsonArray()) {
final JsonArray array = json.getAsJsonArray();
for (int i = 0; i < array.size(); ++i) {
final JsonElement element = array.get(i);
final Object deserialize = context.deserialize(element, rawType);
collection.add(deserialize);
}
} else {
// final Object deserialize = context.deserialize(json,
// rawType);
// collection.add(deserialize);
}
return collection;
} catch (final Exception e) {
logger.error(e.getMessage(), e);
}
return null;
}
}
As you can see in this example, I am getting to a point where the deserializer doesn't get a json array - but MyClass (from Collection - this is a little bit weird for me - because I get those elements one by one, not via array.
Activity
kiptoomm commentedon Oct 13, 2015
Was this ever released? I'm using Gson 2.3.1 and don't see it..
Cy4n1d3 commentedon Nov 13, 2015
I don't think so.
Guess I'll either have to write some generic converters or switch back to Jackson, as I rely on loads of Collections filled with abstract classes for a project...
JonasVautherin commentedon Apr 7, 2016
GsonFire does something that could help (see "Type Selectors" here)
Cy4n1d3 commentedon Apr 7, 2016
Didn't know about that, thanks for the heads up!
Might come in handy some day 👍
subha-sam commentedon Jul 26, 2016
Hey guys ,
I have a similar usecase as this
Class A{
// fields
}
Class B extends A{
// fields
}
Class C extends A{
// fields
}
Class D extends A{
// fields
}
Class Test extends A{
public List contents = new ArrayList(); // it may contain A, B, C etc.
private boolean isHeader = false;
private String myTestString = "test";
}
I am trying to serialize "contents " collection using gson libarary.
can someone tell me whats the solution for this. I found using RuntimeTypeAdaptorFactory would solve it but, I using gson 2..5, in that version I dont see this class.
Struck with this issues for a past three days. writing custom serializations code for my usecase runs for pages.kindly help. whats the work around that the current gson library is having.
inder123 commentedon Jul 27, 2016
Copy over RuntimeTypeAdapterFactory code. It is meant to be used as copied source-code.
mgerhardy commentedon Mar 27, 2017
Add pull request #1055 that shows a few issues regarding Collection. I would be glad about feedback.
My problem is that I need to deserialize Collections at runtime - thus I can't use the new TypeToken<List>() {}.getType() syntax. I only have a Class instance. Do I have to register some special type of Collection adapter or JsonDeserializer? I tried to add a deserializer but this wasn't possible because I lack needed types for fromJson calls.
As you can see in this example, I am getting to a point where the deserializer doesn't get a json array - but MyClass (from Collection - this is a little bit weird for me - because I get those elements one by one, not via array.