我在Android应用程序(使用Gson库)中实现Json反序列化时遇到一些问题
我曾经这样上课
public class MyJson<T>{
public List<T> posts;
}
而反序列化调用是:
public class JsonDownloader<T> extends AsyncTask<Void, Void, MyJson<T>> {
...
protected MyJson<T> doInBackground(Void... params) {
...
Reader reader = new InputStreamReader(content);
GsonBuilder gson = new GsonBuilder();
Type collectionType = new TypeToken<MyJson<T>>() {}.getType();
result = gson.create().fromJson(reader, collectionType);
...
}
}
问题是调用后的result.posts列表保存了一个LinkedTreeMap对象数组(值正确,因此问题是反序列化),而不是MyJson对象。当我使用MyObject而不是T时,一切都运行良好,MyObject是正确的。
那么,有没有办法在不创建自定义反序列化程序的情况下实现反序列化调用呢?
6条答案
按热度按时间xggvc2p61#
你必须在反序列化的时候指定
T
的类型。如果Gson
不知道示例化什么Type
,你将如何创建posts
的List
?它不能永远保持T
。所以,你将提供T
类型作为Class
参数。现在,假设
posts
的类型是String
,您将把MyJson<String>
反序列化为(为了简单起见,我还添加了一个String json
参数;您将像以前一样从reader
读取):类似地,要反序列化
Boolean
对象的MyJson
在我的例子中,我假设
MyJson<T>
为因此,如果您要寻找来还原序列化
List<MyObject>
,您应该以下列方式叫用方法xqkwcwgp2#
你试过吗?
编辑
在阅读this的帖子之后,似乎你对
Type
的使用是正确的。我相信你的问题是T
的使用。你必须记住,Java有类型擦除。这意味着在运行时,所有T
的示例都被Object
替换。因此,在运行时,你传递给GSON的实际上是MyJson<Object>
。如果你尝试用一个具体的类来代替<T>
,我相信它会起作用。Google Gson - deserialize list object? (generic type)
apeeds0o3#
所以上面的答案对我不起作用,经过反复试验后,我的代码就这样结束了:
这里的重要部分是方法签名,包括左边的"< T >“。
当调用Gson时,该方法接收泛型对象的TypeToken。
最后,TypeToken可以使用MyDTO,甚至是一个简单的对象,只是MyDTO。
vcudknz34#
对于任何像我一样和Kotlin斗争的人来说,我找到了这样的工作方式
请注意,调用泛型函数需要在调用站点的函数名后面有类型参数(请参见此处)
83qze16e5#
如果您使用的是gson 2.8.0或更高版本,则可以使用以下方法
TypeToken#getParametized((Type rawType, Type... typeArguments))
示例:
我相信这对你的情况会起作用。
感谢this answer。
9jyewag06#
我用上面的答案在Kotlin中找到了更通用的方法(但你可以在java中稍作调整后重用)我有
BaseDB<T>
,它加载Table<T>
,而Table有List<T>