先看一下以下代码了解问题
ObjectMapper objectMapper = new ObjectMapper()
.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
// Map<Integer, Integer> map1 = new HashMap<>();
// map1.put(1, 1);
Map<Integer, Integer> map1 = ImmutableMap.of(1, 1);
// 使用 HashMap 时,content 是`["java.util.HashMap",{"1":1}]`;而使用 ImmutableMap 时是`{"1":1}`
String content = objectMapper.writeValueAsString(map1);
// 因为使用 ImmutableMap 时没有了类型信息,反序列化会报错。
// com.fasterxml.jackson.databind.exc.MismatchedInputException: Unexpected token (START_OBJECT), expected START_ARRAY: need JSON Array to contain As.WRAPPER_ARRAY type information for class java.util.Map
at [Source: (String)"{"1":1}"; line: 1, column: 1]
Map<Integer, Integer> map2 = objectMapper.readValue(content, new TypeReference<Map<Integer, Integer>>() {
});
按照JacksonPolymorphicDeserialization · FasterXML/jackson-docs Wiki所描述的,如果我没有理解错的话,使用 ImmutableMap 时没有保存类型信息是因为ImmutableMap.of(1, 1)
会产生SingletonImmutableBiMap
,而SingletonImmutableBiMap
是 final 的。
但是四种ObjectMapper.DefaultTyping
( JAVA_LANG_OBJECT, OBJECT_AND_NON_CONCRETE, NON_CONCRETE_AND_ARRAYS, NON_FINAL )都无法实现“保存SingletonImmutableBiMap
这个类型信息”。而ObjectMapper.setDefaultTyping(...)
也是依赖于ObjectMapper.DefaultTyping
的,所以也不行。
问题:Jackson 能够保存 final 类型的类型信息吗?如果可以的话,应该怎么做呢?
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.