How to support serialization for sub classes(support polymorphism)

2,276 views
Skip to first unread message

Kesava Neeli

unread,
Mar 15, 2012, 1:33:58 PM3/15/12
to google-gson
Hi,

I have a sample structure like this.
Class A {
List<Vehicle>
}
Class Vehicle {
some fields
}
Class Car extends Vehicle {
some fields
}
Class Honda extends Car {
some fields
}

When I do gson.toJson( instance of class A), the fields only in
Vehicle are serailized to json which is expected. It goes by the
static type. The actual list of objects in Class A are of Honda type.
Is there a way to use gson library to cover this case? Something like
RuntimeTypeAdapter factory. I found this discussion
http://code.google.com/p/google-gson/issues/detail?id=231 which is
exactly I was looking for..

Anyone has suggestions on how to support this?




Brandon Mintern

unread,
Mar 15, 2012, 3:35:27 PM3/15/12
to googl...@googlegroups.com
I'm pretty sure it already works exactly the way you want:

// File subclass.java

import com.google.gson.Gson;
import java.util.ArrayList;
import java.util.List;

public class subclass {
static class A {
List<Vehicle> vehicles = new ArrayList();
}
static class Vehicle {
String type;
Vehicle (String type) {
this.type = type;
}
}
static class Car extends Vehicle {
String make;
Car (String make) {
super("Car");
this.make = make;
}
}
static class Honda extends Car {
String model;
public Honda (String model) {
super("Honda");
this.model = model;
}
}

public static void main(String[] args) {
A a = new A();
a.vehicles.add(new Honda("Civic"));
a.vehicles.add(new Honda("Accord"));
a.vehicles.add(new Car("Toyota"));
a.vehicles.add(new Vehicle("Truck"));
System.out.println(new Gson().toJson(a));
}
}

$ javac -cp gson-2.1.jar subclass.java
$ java -cp .:gson-2.1.jar subclass
{"vehicles":[{"model":"Civic","make":"Honda","type":"Car"},{"model":"Accord","make":"Honda","type":"Car"},{"make":"Toyota","type":"Car"},{"type":"Truck"}]}

Am I misunderstanding your problem?

> --
> You received this message because you are subscribed to the Google Groups "google-gson" group.
> To post to this group, send email to googl...@googlegroups.com.
> To unsubscribe from this group, send email to google-gson...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/google-gson?hl=en.
>

Kesava Neeli

unread,
Mar 15, 2012, 5:33:46 PM3/15/12
to google-gson
Thanks for example.. It didn't work for me. I added a custom adapter
to my class like in TypeHierarchyAdapterTest.java in the gson test
cases. That worked but it's a maintainence headache.. We have to
modify the adapter whenever we add new sub classes deriving from the
main base class.

The difference I see is that I use gson 1.7.1 and your json lib is
2.1.

Thanks
Neeli
> >http://code.google.com/p/google-gson/issues/detail?id=231which is

Kesava Neeli

unread,
Mar 15, 2012, 6:19:06 PM3/15/12
to google-gson
I confirm that my codebase worked with gson-2.1.jar file without any
custom type adapters for my hierarchical class. I wish I upgraded to
latest jars sooner. Thanks for a working example anyway.

Thanks
Neeli

Brandon Mintern

unread,
Mar 15, 2012, 6:35:08 PM3/15/12
to googl...@googlegroups.com
Sure! I'm glad that everything is working for you now :)

Kesava Neeli

unread,
Mar 15, 2012, 8:48:50 PM3/15/12
to google-gson
Hi,

Have you tried it to de-serialize it? Looks like de-serialize is not
smart to know the structure. I used the same example and used the json
string output of serialize. See the output below. My requirement is
that I need to support both.

public class GsonTest {
private static final String JSON_STR = "{\"vehicles\":[{\"model\":
\"Civic\",\"make\":\"Honda\",\"type\":\"Car\"},{\"model\":\"Accord\",
\"make\":\"Honda\",\"type\":\"Car\"},{\"make\":\"Toyota\",\"type\":
\"Car\"},{\"type\":\"Truck\"}]}";

static class A {
List<Vehicle> vehicles = new ArrayList();
}
static class Vehicle {
String type;
Vehicle (String type) {
this.type = type;
}
}
static class Car extends Vehicle {
String make;
Car (String make) {
super("Car");
this.make = make;
}
}
static class Honda extends Car {
String model;
public Honda (String model) {
super("Honda");
this.model = model;
}
}

public static void main(String[] args) {
/*A a = new A();
a.vehicles.add(new Honda("Civic"));
a.vehicles.add(new Honda("Accord"));
a.vehicles.add(new Car("Toyota"));
a.vehicles.add(new Vehicle("Truck"));
System.out.println(new Gson().toJson(a));*/

A myA = new Gson().fromJson(JSON_STR, A.class);
System.out.println("json after de-serialize = " + new
Gson().toJson(myA));
}
}

output is json after de-serialize = {"vehicles":[{"type":"Car"},
{"type":"Car"},{"type":"Car"},{"type":"Truck"}]}

Thanks
Neeli

Brandon Mintern

unread,
Mar 15, 2012, 8:59:48 PM3/15/12
to googl...@googlegroups.com
In this case, Gson has no way of knowing what type you want to
deserialize to. You would have to register a deserializer for Vehicle
which would figure out what type it should create. This comment in the
issue tracker shows one way to do so:

http://code.google.com/p/google-gson/issues/detail?id=43#c15

Kesava Neeli

unread,
Mar 16, 2012, 12:50:19 AM3/16/12
to google-gson
Yep. I already implemented a custom de-serializer and it works. Gson
source code has an example for TypeHeirarchyAdapter. I don't think
it's possible for a parser to know the type to de-serialize.
Reply all
Reply to author
Forward
0 new messages