有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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) 个答案

  1. # 1 楼答案

    查看convertValue的代码,您会发现

        if (targetType != Object.class
                && !toValueType.hasGenericTypes()
                && targetType.isAssignableFrom(fromValue.getClass())) {
            return fromValue;
        }
    

    因此,在您的例子中,如果map.get(key)MyPojo类型,那么convertValue()方法确实会返回对输入的引用。这就解释了为什么在更改“已转换”对象时,贴图中的值会发生变化

    现在你的问题可以归结为如何克隆一个物体,这通常是一个复杂的话题

    • 如果需要安全的深度复制,可以序列化和反序列化对象。但是,此过程的性能很差

    • 您可以实现clone()方法并标记类Cloneable,这是一种非常常见的解决方案,可以为您提供控制和良好的性能

    • 您还可以查看Apache Commons BeanUtils,它有cloneBean()方法,使用getter和setter克隆对象的属性