我有以下课程:
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
- 类从上面改为
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 :(得分:0)
我不知道答案,但我知道泛型类型解析是一件很难解决的事情:特别是从类型参数T到接口到泛型参数声明(T = Long)的接口的完整类型解析。在这些情况下,仅检查Method对象的参数还不足以解析泛型类型参数。这很可能是导致问题的原因;它可能是Gson中的一个错误。
既然你要序列化东西,也许你可以省略任何类型的声明?虽然你的TypeToken对于用例是正确的,但也许它会让Gson感到困惑。
但是,如果你不能让Gson使用它,我知道其他JSON库Jackson可以正确处理这些情况。
答案 1 :(得分: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);
}