对同一个Object使用两种不同的序列化方法

时间:2010-08-20 07:41:29

标签: java serialization

我有一个街道的城市地图,我需要(取消)序列化。每条街道都由City和id标识,如下所示:

private final City city;
private final long id;

该城市包含该城市所有街道的列表(City.streetList),因此在保存模型时我可以执行类似

的操作
serializeToFile(modelFile, currentCity);

这有效并且没有问题,但现在我想通过网络发送街道(也使用序列化)。当我对街道进行序列化时,显然城市对象也会被序列化,因此所有街道都会被序列化,从而导致非常大的数据包大小。显然。

我不能让city瞬态,因为需要唯一识别街道。我也不能让City.streetList瞬态,因为我需要我的模型列表。

每个城市都有一个唯一的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.setWritingToNetwork(true)似乎不仅仅是丑陋)并且这可能不是一个好的解决方案吗?

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

2 个答案:

答案 0 :(得分:2)

如果您无法知道对象被序列化为文件或网络,您应该始终写出城市ID而不是整个城市。有一个方法可以通过ID来查找城市。

另一种使用方法是序列化代理。在此pdf中查看有关它的详细信息:Effective Java Reloaded。基本上,序列化代理与使用对象的逻辑状态序列化的对象完全不同。该对象重写writeReplace和readResolve方法以编写代理而不是此对象,并通过读取代理创建对象。代理人也只会写城市ID,而不是整个城市。

答案 1 :(得分:2)

一种解决方法可能是重新设计您的应用程序,以便您的Street对象不再包含对城市的引用,而只包含“城市ID”。城市对象可以转到单独的哈希映射:

private final long cityId;
private final long id;

和某处的转换器:

public static City getCity(long id) {
  return cityMap.get(id);
}

序列化街道对象将变得非常小,您只需序列化并存储或发送citymap一次。