1

我有以下课程:

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)
        ...

那么,我该怎么做才能完成这项工作?

4

2 回答 2

0

我不知道答案,但我知道泛型类型解析是一件很棘手的事情:特别是从具有类型参数 T 的接口到泛型参数声明 (T=Long) 的完整类型解析。在这些情况下,仅检查 Method 对象的参数并解析泛型类型参数是不够的。这很可能是导致问题的原因;这可能是 Gson 中的错误。

由于您正在序列化事物,也许您可​​以省略任何类型声明?尽管您的 TypeToken 对于用例来说是正确的,但它可能会让 Gson 感到困惑。

但以防万一你不能让 Gson 使用它,我知道其他 JSON 库杰克逊可以正确处理这种情况。

于 2010-11-23T01:04:10.440 回答
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);
}
于 2011-06-10T12:47:58.420 回答