V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
weofuh
V2EX  ›  问与答

Java 引用对象导致 jackson 反序列化结果不正确

  •  
  •   weofuh · 2022-11-21 14:45:40 +08:00 · 1060 次点击
    这是一个创建于 740 天前的主题,其中的信息可能已经有所发展或是发生改变。

    为什么会使 map value 的 list 元素重复?

    import com.fasterxml.jackson.databind.ObjectMapper;
    
    import java.util.Arrays;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    public class Test {
    
        public static void main(String[] args) throws Exception {
            ObjectMapper jackson = new ObjectMapper();
    
            Map<String, List<String>> map = new HashMap<>();
            map.put("key", Arrays.asList("a", "b", "c"));
    
            DataInfo dataInfo = new DataInfo(map);
    
            // {"map":{"key":["a","b","c"]},"copyList":["a","b","c"]}
            String json = jackson.writeValueAsString(dataInfo); 
    
            System.out.println(dataInfo.getMap().get("key").size()); // 3
    
            DataInfo di = jackson.readValue(json, DataInfo.class);
            System.out.println(di.getMap().get("key").size()); // 6
        }
    
        static class DataInfo {
            private Map<String, List<String>> map;
    
            public DataInfo() {
            }
    
            public DataInfo(Map<String, List<String>> map) {
                this.map = map;
            }
    
            //@Transient
            public List<String> getCopyList() {
                return map.get("key");
                //return new ArrayList<>(map.get("key"));
            }
    
            public Map<String, List<String>> getMap() {
                return map;
            }
    
            public void setMap(Map<String, List<String>> map) {
                this.map = map;
            }
        }
    }
    
    
    3 条回复    2022-11-21 15:59:50 +08:00
    urnoob
        1
    urnoob  
       2022-11-21 15:04:59 +08:00   ❤️ 1
    ```
    Object toModify;
    try {
    toModify = this._getter.invoke(instance, (Object[])null);
    } catch (Exception var6) {
    this._throwAsIOE(p, var6);
    return;
    }

    if (toModify == null) {
    ctxt.reportBadDefinition(this.getType(), String.format("Problem deserializing 'setterless' property '%s': get method returned null", this.getName()));
    }
    this._valueDeserializer.deserialize(p, ctxt, toModify);
    ```
    copyList 解析时 _getter 是 getCopyList , toModify 就是 map.get("key") 的结果 ,两者一 merge 不就是 6 了么。

    感觉 DataInfo 的写法也很奇葩的,jackson 也是挺辛苦 为了方便大家提供了各种奇葩姿势的支持。

    最后吐槽下 不是说 lz ,普遍现象,现在写 java 的人是真多,title 越高,代码越烂,反正不影响业务跑就行(影响了只要人人能跑也行)
    weofuh
        2
    weofuh  
    OP
       2022-11-21 15:48:50 +08:00
    @urnoob 哈哈哈,上午 debug 了下,没搞懂为啥要 merge 进 map 的 list 里去,是有什么规范或者约定啥的。提供类似 getCopyList 这样方法的同事可能是方便在其他地方使用的时候不需要关心 map 里的 key 是什么吧,因为我看到了好几个类似的 get 方法。
    JYii
        3
    JYii  
       2022-11-21 15:59:50 +08:00
    一开始还没出来, debug 进去发现怎么有个 CopyList, 已经想开喷了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1021 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 19:14 · PVG 03:14 · LAX 11:14 · JFK 14:14
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.