2010-09-15 94 views
1

我有下面的类继承:Gson.toJson(),从一个普通类

public static class TestSomething { 

    Integer test; 

    public TestSomething(Integer test) { 
     this.test = test; 
    } 

    // getter and setter for test 
} 

好了,现在GSON创建这个类的集合,其序列:

Collection<TestSomething> tests = Arrays.asList(
    new TestSomething(1), 
    new TestSomething(2), 
    new TestSomething(3) 
); 
String json = new Gson().toJson(tests, new TypeToken<Collection<TestSomething>>() {}.getType()); 

后对此,字符串json设置为

[{"test":1},{"test":2},{"test":3}] 

这是伟大的。

但是现在,我所有的模型类都继承了一个通用类型Identifiable<T>,它只提供了两种方法T getId()void setId(T)。所以我改变TestSomething -class从上面

public static class TestSomething extends Identifiable<Long> { 
    // same as above 
} 

当我试图通过Gson.toJson()把这个,GSON结束,以下情况例外:

java.lang.UnsupportedOperationException: Expecting parameterized type, got class path.to.TestSomething. 
Are you missing the use of TypeToken idiom? 
See http://sites.google.com/site/gson/gson-user-guide#TOC-Serializing-and-Deserializing-Gener 
     at com.google.gson.TypeInfoFactory.getActualType(TypeInfoFactory.java:97) 
     ... 

所以,我有什么做得到这份工作?

回答

0

我不知道答案,但我知道泛型类型的解析是一个棘手的事情,要正确地做到:特别是从类型参数T到接口泛型参数声明(T = Long)的完整类型解析。在这些情况下,检查Method对象的参数还不足以解决泛型类型参数。这很可能是导致问题的原因;它可能是Gson的一个bug。

既然你是序列化的东西,也许你可以忽略任何类型的声明?尽管你的TypeToken对于用例是正确的,但也许它会混淆Gson。

但是,如果你不能让Gson与此工作,我知道其他JSON库Jackson可以正确处理这种情况。

0

也许这个问题在一个Gson版本中解决了,比原始提问者使用的更新,因为原始问题中的示例现在按预期序列化。

// output: 
// [{"test":1},{"test":2},{"test":3}] 

import java.util.Arrays; 
import java.util.Collection; 

import com.google.gson.Gson; 
import com.google.gson.reflect.TypeToken; 

public class Foo 
{ 
    public static void main(String[] args) 
    { 
    Collection<TestSomething> tests = Arrays.asList(
     new TestSomething(1), 
     new TestSomething(2), 
     new TestSomething(3)); 
    String json = new Gson().toJson(tests, new TypeToken<Collection<TestSomething>>() {}.getType()); 
    System.out.println(json); 
    } 
} 

class TestSomething extends Identifiable<Long> 
{ 
    Integer test; 

    public TestSomething(Integer test) 
    { 
    this.test = test; 
    } 

    @Override 
    Long getId() 
    { 
    return new Long(test); 
    } 

    @Override 
    void setId(Long t) 
    { 
    this.test = (int)(t.longValue()); 
    } 
} 

abstract class Identifiable<T> 
{ 
    abstract T getId(); 
    abstract void setId(T t); 
} 
相关问题