sangmingming / google-gson

Automatically exported from code.google.com/p/google-gson
0 stars 0 forks source link

No support for fields whose types are type parameters #168

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Assume you have the following 2 classes:
class Entity<IDT,NameT>{
    IDT id;
    NameT name;

    public Entity(IDT id, NameT name) {
        super();
        this.id = id;
        this.name = name;
    }
    public IDT getId() {
        return id;
    }
    public NameT getName() {
        return name;
    }
}

class Employee extends Entity<Integer,String>{
    double age; 
    private int tag;

    public Employee() {
        super(0,null);
    }
    public Employee(int id, String name, double age) {
        super(id,name);
        this.age = age;
    }

    public double getAge() {
        return age;
    }

    void setTag(int tag){
        this.tag = tag;
    }   
}

when trying to use 
  new GsonBuilder().create().toJson(new Employee(1,"Mary",10)); it throws 

java.lang.UnsupportedOperationException: Expecting parameterized type, got
class test.gson.Employee.
 Are you missing the use of TypeToken idiom?
 See
http://sites.google.com/site/gson/gson-user-guide#TOC-Serializing-and-Deserializ
ing-Gener

ok, then I try the generic one using 
new GsonBuilder().create().toJson(new Employee(1,"Mary",10),new
TypeToken<Employee>(){}.getType()); Gson will only show id/name field, all
other field in Employee class is ignored. any solution? 

I've refered <a
href="http://code.google.com/p/google-gson/source/browse/trunk/gson/src/test/jav
a/com/google/gson/functional/ParameterizedTypesTest.java">,
but didn't help.

please help to solve the problem. thanks!

Original issue reported on code.google.com by hnjch...@gmail.com on 26 Oct 2009 at 8:49

GoogleCodeExporter commented 9 years ago
by the way, I tried this under both 1.3/1.4 beta, both threw the same exception

Original comment by hnjch...@gmail.com on 26 Oct 2009 at 8:51

GoogleCodeExporter commented 9 years ago
I am having the same issue as well.

I am using the 1.4 version on Ubuntu.

Is there any solution for this?  

Original comment by ekaqu1...@gmail.com on 14 Mar 2010 at 6:03

GoogleCodeExporter commented 9 years ago
Pls refer to the gson's guide for generic class:

Serializing and Deserializing Generic Types
When you call toJson(obj), Gson calls obj.getClass() to get information on the 
fields
to serialize. Similarly, you can typically pass MyClass.class object in the
fromJson(json, MyClass.class) method. This works fine if the object is a 
non-generic
type. However, if the object is of a generic type, then the Generic type 
information
is lost because of Java Type Erasure. Here is an example illustrating the point:

List<String> myStrings = new List<String>();
gson.toJson(myStrings); // Will cause a runtime exception

gson.fromJson(json, myStrings.getClass());

The above call results in a runtime exception because Gson invokes
myStrings.getClass() to get its class information, but this method returns a raw
class, List.class. This means that Gson has no way of knowing that this is a 
list of
Strings, and not plain objects.

You can solve this problem by specifying the correct parameterized type for your
generic type. You can do this by using the TypeToken class.
Type listType = new TypeToken<List<String>>() {}.getType();
gson.toJson(myStrings, listType);

gson.fromJson(json, listType);

The idiom used to get listType actually defines an anonymous local inner class
containing a method getType() that returns the fully parameterized type. 

Original comment by pvthang...@gmail.com on 22 Apr 2010 at 3:38

GoogleCodeExporter commented 9 years ago
The core problem is that GSON isn't tracking that the type of 'IDT' will be 
'Integer' for Employee instances.

Original comment by limpbizkit on 1 Nov 2010 at 11:10

GoogleCodeExporter commented 9 years ago
I've attached a patch that uses type mojo stolen from Guice. In general I think 
it's a big leap forward because it'll give GSON better support for type 
parameters in fields and type arguments of fields. In particular, this should 
work:
  class Foo<K, V> {
    K k1;
    Map<K, V> map;
    List<V> list;
  }

More interestingly, these should also work:
  class WackyHashMap<V, K> extends HashMap<K, V> {...}
  class SecondArgCollection<A, B> implements Collection<B> {...}

I'd prefer not to commit this change in time for GSON 1.6 because this change 
is destabilizing. It's a large change and we can build upon it by using 
TypeToken internally everywhere instead of TypeInfo.

Original comment by limpbizkit on 2 Nov 2010 at 8:08

Attachments:

GoogleCodeExporter commented 9 years ago

Original comment by inder123 on 3 Nov 2010 at 1:47

GoogleCodeExporter commented 9 years ago
The attached patch resolves merge conflicts.

Original comment by limpbizkit on 3 Nov 2010 at 3:12

Attachments:

GoogleCodeExporter commented 9 years ago
Issue 241 has been merged into this issue.

Original comment by limpbizkit on 3 Nov 2010 at 3:16

GoogleCodeExporter commented 9 years ago
Issue 40 has been merged into this issue.

Original comment by limpbizkit on 3 Nov 2010 at 3:20

GoogleCodeExporter commented 9 years ago
This issue was closed by revision r707.

Original comment by limpbizkit on 19 Jan 2011 at 10:24