Generics 当键不是基元时反序列化泛型哈希映射

Generics 当键不是基元时反序列化泛型哈希映射,generics,gson,Generics,Gson,我想使用泛型对哈希映射进行gson和de gson操作。 当我的密钥是字符串时,我可以成功地完成它,但如果它是 对象。 我这里有两个代码部分。第一个不行,第二个不行 是的 // doesnt work works try { TradableBean tradable = new TradableBean("Tradable"); PositionBean position = new PositionBean(tradable); Map<Tr

我想使用泛型对哈希映射进行gson和de gson操作。
当我的密钥是字符串时,我可以成功地完成它,但如果它是 对象。
我这里有两个代码部分。第一个不行,第二个不行 是的

// doesnt work works
 try {
       TradableBean tradable = new TradableBean("Tradable");
       PositionBean position = new PositionBean(tradable);
       Map<TradableBean, PositionBean> map1 = new HashMap<TradableBean, PositionBean>();
       map1.put(tradable, position);
       String json1 = gson.toJson(map1);
       Map<TradableBean, PositionBean> map2 = gson.fromJson(json1, new TypeToken<Map<TradableBean, PositionBean>>(){}.getType());
       System.out.println(map2);
   } catch (Exception e) {
       System.out.println("failed");
   }
}

例外情况:

com.google.gson.JsonParseException: Expecting object found: "TradableBean{id=0, tradableName='Tradable', moneyMultiplier=1, expirationDate=null}"

我认为你需要自己写

更新:故障指示灯是例外:

com.google.gson.JsonParseException: Expecting object found: "TradableBean{id=0, tradableName='Tradable', moneyMultiplier=1, expirationDate=null}"

前置字符串“TradableBean”似乎是由使用某种
toString()
的序列化编写的。反序列化需要一个形式为
{id=0,…}

的对象,Dan的答案是正确的

您遇到的Gson限制涉及它当前如何序列化映射键:通过调用
toString()
。发件人:

MapTypeAdapter
文档中也描述了此行为

这个实现实际上只适用于简单的基元类型作为映射键。如果键不是简单的原语,则对象是{@code-toString},该值用作其键

如果您坚持使用自定义类型作为映射键,那么我可以告诉您,您必须编写自定义序列化程序和/或自定义反序列化程序和/或生成易于反序列化的字符串表示形式的
toString()


另外,请看一个方法。(它可以通过调用
GsonBuilder.enableComplexMapKeySerialization()
使用,而不是通过文档描述的直接实例化(因为它目前不是一个公共类)。我没有测试它的实现是否有效,但它看起来很有希望。)

Hi,每当我传递TradableBean时,我都会使用它的默认序列化,它工作正常。它在api中没有说它不应该在映射的键上使用常规反序列化。我错了吗?嗨,谢谢你的新数据。我删除了前置字符串,但仍然没有结果。我也试着移除我的toString。它到底在等待什么进入关键对象的toString?我还应该写自定义序列化吗?@450602:是的,自定义序列化是一个两面性的硬币。大多数情况下,您需要实现两个方向。此外,Gson.decode()上还有严格标志。。。看看这是否有任何影响。我几乎找不到关于这方面的文件。你发送给我的链接不提供示例。如果你知道,如果你把它here@450602:很抱歉,你没有发现它有用。然而,这是最权威的文件。您可能希望在此处查看gson测试套件:
com.google.gson.JsonParseException: Expecting object found:
"TradableBean{id=0, tradableName='Tradable', moneyMultiplier=1,
expirationDate=null}"
       at
com.google.gson.JsonObjectDeserializationVisitor.visitFieldUsingCustomHandler(JsonObjectDeserializationVisitor.java:
100)
       at
com.google.gson.ObjectNavigator.navigateClassFields(ObjectNavigator.java:
150)
       at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:123)
       at
com.google.gson.JsonDeserializationContextDefault.fromJsonPrimitive(JsonDeserializationContextDefault.java:
84)
       at
com.google.gson.JsonDeserializationContextDefault.deserialize(JsonDeserializationContextDefault.java:
53)
       at com.google.gson.DefaultTypeAdapters
$MapTypeAdapter.deserialize(DefaultTypeAdapters.java:531)
       at com.google.gson.DefaultTypeAdapters
$MapTypeAdapter.deserialize(DefaultTypeAdapters.java:498)
       at
com.google.gson.JsonDeserializerExceptionWrapper.deserialize(JsonDeserializerExceptionWrapper.java:
50)
com.google.gson.JsonParseException: Expecting object found: "TradableBean{id=0, tradableName='Tradable', moneyMultiplier=1, expirationDate=null}"
map.add(String.valueOf(entry.getKey()), valueElement);