Jackson备选方案的java价值问题?
我正试着了解一下杰克逊的convertValue
方法。起初我认为它在某种程度上等同于Gson#fromJson
方法,但事实似乎并非如此
问题是:
// Map<String, Object> map = ...
ObjectMapper mapper = new ObjectMapper();
MyPojo pojo = mapper.convertValue(map.get(key), MyPojo.class);
for (Map.Entry<String, Object> m : map.entrySet()) {
System.out.println("k=" + m.getKey() + " v=" + m.getValue());
}
pojo.name = "Banana";
for (Map.Entry<String, Object> m : map.entrySet()) {
System.out.println("k=" + m.getKey() + " v=" + m.getValue());
}
输出
k=66e8c013 v=MyPojo{name='Apple'}
k=66e8c013 v=MyPojo{name='Banana'}
注意:代码和输出已精简到相关部分
因此,如果我修改我的pojo对象,它在原始Map
中也会发生变化。对我来说,Jackson似乎不会在内部调用“new MyPojo()”,然后为每个找到的变量设置值
我能做些什么来防止这种情况?有别的方法吗?我是否需要创建一个复制构造函数,以便在不引用映射中的值的情况下获得一个真正的新对象
此外,如果有人能告诉我convertValue
实际上做了什么,那就太酷了
# 1 楼答案
查看
convertValue
的代码,您会发现因此,在您的例子中,如果
map.get(key)
是MyPojo
类型,那么convertValue()
方法确实会返回对输入的引用。这就解释了为什么在更改“已转换”对象时,贴图中的值会发生变化现在你的问题可以归结为如何克隆一个物体,这通常是一个复杂的话题
如果需要安全的深度复制,可以序列化和反序列化对象。但是,此过程的性能很差
您可以实现
clone()
方法并标记类Cloneable
,这是一种非常常见的解决方案,可以为您提供控制和良好的性能您还可以查看Apache Commons BeanUtils,它有
cloneBean()
方法,使用getter和setter克隆对象的属性