Java 对同一对象使用两种不同的序列化方法

Java 对同一对象使用两种不同的序列化方法,java,serialization,Java,Serialization,我有一张城市地图,上面有我需要(反)序列化的街道。每条街道由城市和id标识,如下所示: private final City city; private final long id; 城市包含该城市所有街道的列表(city.streetList),因此在保存模型时,我可以执行以下操作 serializeToFile(modelFile, currentCity); 这可以工作并且不会引起任何问题,但是现在我想通过网络发送街道(也使用序列化)。当我序列化街道时,显然city对象也会被序列化,因

我有一张城市地图,上面有我需要(反)序列化的街道。每条街道由城市和id标识,如下所示:

private final City city;
private final long id;
城市包含该城市所有街道的列表(
city.streetList
),因此在保存模型时,我可以执行以下操作

serializeToFile(modelFile, currentCity);
这可以工作并且不会引起任何问题,但是现在我想通过网络发送街道(也使用序列化)。当我序列化街道时,显然city对象也会被序列化,因此所有街道都会被序列化,从而导致非常大的数据包大小

我不能使城市成为暂时的,因为它需要唯一地识别街道。我也不能使城市。街道列表暂时化,因为我需要我的模型的列表

每个城市都有一个唯一的ID,所以这样的事情应该是可能的

private void writeObject(ObjectOutputStream out) throws IOException {
    if (serializeForNetwork) { // How can I know this here?
        out.writeObject(city.getId());
    } else {
        out.writeObject(city);
    }
    out.write(id);
}
如上所述,我不知道对象应该如何知道它正在写入网络(在序列化之前调用
street.setwritingtonework(true)
),也许这不是一个好的解决方案


非常感谢您的任何想法!:-)

如果您无法知道对象正在被序列化为文件或通过网络,您应该始终写入城市id,而不是整个城市。有一种方法可以让城市在有身份证的情况下被查询


另一种使用方法是序列化代理。请参阅此pdf中的详细信息:。基本上,序列化代理与使用对象的逻辑状态序列化的对象是完全不同的类。该对象重写writeReplace和readResolve方法,以编写代理而不是此对象,并通过读取代理创建对象。代理还将只写入城市id,而不写入整个城市。

一个解决办法是重新设计应用程序,使街道对象不再包含对城市的引用,而只包含“城市id”。城市对象可以转到单独的哈希映射:

private final long cityId;
private final long id;
还有一个转换器:

public static City getCity(long id) {
  return cityMap.get(id);
}
序列化的街道对象将变得非常小,您只需序列化并存储或发送一次
citymap