我有同样/类似的问题。在稍微不同的上下文中给出更清晰的答案:
我有以下方法产生错误“com.google.gson.internal.LinkedTreeMap 无法转换为 MyType”:
/**
* Reads a LinkedHashMap from the specified parcel.
*
* @param <TKey>
* The type of the key.
* @param <TValue>
* The type of the value.
* @param in
* The in parcel.
* @return Returns an instance of linked hash map or null.
*/
public static <TKey, TValue> LinkedHashMap<TKey, TValue> readLinkedHashMap(Parcel in) {
Gson gson = JsonHelper.getGsonInstance();
String content = in.readString();
LinkedHashMap<TKey, TValue> result = gson.fromJson(content, new TypeToken<LinkedHashMap<TKey, TValue>>(){}.getType());
return result;
}
我想要一种简单的通用方法来读/写链接的哈希图。上述解决方案不起作用,因为据我所知,带有 TKey 和 TValue 的 TypeToken 的类型信息在编译后将丢失。这就是问题所在。如果您将代码更改为以下示例,那么它就可以工作,因为现在我们显式定义了类型标记。我对java不太感兴趣,所以我理解为什么在这种情况下可以在运行时读取类型信息。
/**
* Reads a LinkedHashMap from the specified parcel.
*
* @param <TKey>
* The type of the key.
* @param <TValue>
* The type of the value.
* @param in
* The in parcel.
* @return Returns an instance of linked hash map or null.
*/
public static <TKey, TValue> LinkedHashMap<TKey, TValue> readLinkedHashMap(Parcel in, TypeToken<LinkedHashMap<TKey, TValue>> typeToken) {
Gson gson = JsonHelper.getGsonInstance();
Type type = typeToken.getType();
String content = in.readString();
LinkedHashMap<TKey, TValue> result = gson.fromJson(content, type);
return result;
}
现在您可以像这样调用上面的函数:
readLinkedHashMap(in, new TypeToken<LinkedHashMap<UUID, MyObject>>(){});
旁注 1:编写 linkedhashmap 时,根本不需要指定任何类型标记。 toJson(map) 就足够了。
旁注 2(针对我遇到的问题):默认情况下,gson 使用 toString() 来序列化密钥。如果您为键类型(可能是更复杂的类型)注册类型适配器,则在序列化时不会应用此类型适配器,而是在反序列化时应用。这会导致流程不一致并因此失败。以下选项激活复杂的映射键序列化 https://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/GsonBuilder.html#enableComplexMapKeySerialization.
gsonBuilder.enableComplexMapKeySerialization()