You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中LinkedHashMap转Object序列化后变为SQLRow类的问题

问题分析与解决:LinkedHashMap序列化时被识别为SQLRow内部类

问题根源

你在getAsSocketEligibleMap()方法里用了双大括号初始化语法(new LinkedHashMap<>(){{ ... }}),这不是创建原生的LinkedHashMap实例,而是生成了一个LinkedHashMap的匿名内部类,这个类属于SQLRow的内部类,所以类名显示为mirage.database.sql.SQLRow$1。

匿名内部类会隐式持有外部类SQLRow的引用,序列化时不仅需要这个内部类可序列化,接收端也必须有该内部类的定义,这就导致ObjectOutputStream无法将其识别为标准的LinkedHashMap,进而抛出序列化异常。

解决方案

替换双大括号初始化,改用普通的对象创建和填充逻辑,直接返回原生LinkedHashMap实例:

public LinkedHashMap<String, NetworkedSQLObject> getAsSocketEligibleMap(){
    LinkedHashMap<String, NetworkedSQLObject> map = new LinkedHashMap<>();
    Set<Map.Entry<String, SQLObject>> es = data.entrySet();
    Iterator<Map.Entry<String, SQLObject>> i = es.iterator();
    
    while(i.hasNext()){
        Map.Entry<String, SQLObject> entry = i.next();
        Host.instance.getLogger().info("adding NetworkedSQLObject: " + entry.getKey() + ':' + entry.getValue().getType() + " -> " + entry.getValue().getValue());
        map.put(entry.getKey(), new NetworkedSQLObject(entry.getValue()));
    }
    
    return map;
}

补充说明

双大括号初始化的本质是:

  • 第一层大括号定义了LinkedHashMap的匿名子类
  • 第二层大括号是这个子类的实例初始化块
    这种写法看似简洁,但会带来额外的内部类实例、外部类引用,以及序列化、内存泄漏等潜在问题,在需要序列化的场景下绝对要避免。

内容的提问来源于stack exchange,提问作者user18514542

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 02:40:11