Google Gson-反序列化list <class>对象? (通用类型)

我想通过Google Gson传输列表对象,但是我不知道如何反序列化泛型类型。

在查看此内容后我尝试了什么(BalusC的答案):

MyClass mc = new Gson().fromJson(result, new List<MyClass>(){}.getClass());

但是然后我在日食中遇到了一个错误,说“新的List(){}类型必须实现继承的抽象方法...”,如果我使用快速修复方法,则会得到20个以上的方法存根的怪物。

我很确定有一个更简单的解决方案,但是我似乎找不到它!

编辑:

我现在有

Type listType = new TypeToken<List<MyClass>>()
                {
                }.getType();

MyClass mc = new Gson().fromJson(result, listType);

但是,在“ fromJson”行中确实得到以下异常:

java.lang.NullPointerException
at org.apache.harmony.luni.lang.reflect.ListOfTypes.length(ListOfTypes.java:47)
at org.apache.harmony.luni.lang.reflect.ImplForType.toString(ImplForType.java:83)
at java.lang.StringBuilder.append(StringBuilder.java:203)
at com.google.gson.JsonDeserializerExceptionWrapper.deserialize(JsonDeserializerExceptionWrapper.java:56)
at com.google.gson.JsonDeserializationVisitor.invokeCustomDeserializer(JsonDeserializationVisitor.java:88)
at com.google.gson.JsonDeserializationVisitor.visitUsingCustomHandler(JsonDeserializationVisitor.java:76)
at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:106)
at com.google.gson.JsonDeserializationContextDefault.fromJsonArray(JsonDeserializationContextDefault.java:64)
at com.google.gson.JsonDeserializationContextDefault.deserialize(JsonDeserializationContextDefault.java:49)
at com.google.gson.Gson.fromJson(Gson.java:568)
at com.google.gson.Gson.fromJson(Gson.java:515)
at com.google.gson.Gson.fromJson(Gson.java:484)
at com.google.gson.Gson.fromJson(Gson.java:434)

我确实捕获到JsonParseExceptions并且“结果”不为null。

我用调试器检查了listType并得到了以下内容:

  • 清单类型
  • args = ListOfTypes
  • 列表=空
  • resolveTypes =类型[1]
  • 加载程序= PathClassLoader
  • ownerType0 =空
  • ownerTypeRes = null
  • rawType =类(java.util.ArrayList)
  • rawTypeName =“ java.util.ArrayList”

因此似乎“ getClass”调用无法正常工作。有什么建议么...?

编辑2: 我检查了《 Gson用户指南》。它提到了在将通用类型解析为Json期间应该发生的运行时异常。就像在示例中一样,我做到了“错误”(上面未显示),但根本没有得到该异常。因此,我按照用户指南中的建议更改了序列化。不过没有帮助。

编辑3: 解决了,请参阅下面的答案。

最佳答案

反序列化通用集合的方法:

import java.lang.reflect.Type;
import com.google.gson.reflect.TypeToken;

...

Type listType = new TypeToken<ArrayList<YourClass>>(){}.getType();
List<YourClass> yourClassList = new Gson().fromJson(jsonArray, listType);

Since several people in the comments have mentioned it, here's an explanation of how the TypeToken class is being used. The construction new TypeToken<...>() {}.getType() captures a compile-time type (between the < and >) into a runtime java.lang.reflect.Type object. Unlike a Class object, which can only represent a raw (erased) type, the Type object can represent any type in the Java language, including a parameterized instantiation of a generic type.

The TypeToken class itself does not have a public constructor, because you're not supposed to construct it directly. Instead, you always construct an anonymous subclass (hence the {}, which is a necessary part of this expression).

Due to type erasure, the TypeToken class is only able to capture types that are fully known at compile time. (That is, you can't do new TypeToken<List<T>>() {}.getType() for a type parameter T.)

For more information, see the documentation for the TypeToken class.