【问题标题】:Gson.toJson() and inheriting from a generic classGson.toJson() 并从泛型类继承
【发布时间】:2010-09-15 21:55:44
【问题描述】:

我有以下课程:

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&lt;T&gt;,它只提供了两个方法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)
        ...

那么,我必须做什么才能完成这项工作?

【问题讨论】:

    标签: gson


    【解决方案1】:

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

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

    但以防万一您无法让 Gson 使用它,我知道其他 JSON 库 Jackson 可以正确处理此类情况。

    【讨论】:

      【解决方案2】:

      也许这个问题在比原始提问者使用的版本更新的 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);
      }
      

      【讨论】:

        猜你喜欢
        • 2019-07-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-27
        • 2015-09-15
        • 1970-01-01
        • 2014-12-19
        • 1970-01-01
        相关资源
        最近更新 更多