我有一个对象,其中包含一些我想要序列化的不可序列化字段。它们来自一个单独的API,我无法更改它们,因此无法使它们可序列化。主要问题是Location类。它包含我需要的四个可以序列化的内容,都是int。我如何使用read/writeObject创建一个自定义序列化方法,可以执行类似以下操作:
// writeObject:
List<Integer> loc = new ArrayList<Integer>();
loc.add(location.x);
loc.add(location.y);
loc.add(location.z);
loc.add(location.uid);
// ... serialization code
// readObject:
List<Integer> loc = deserialize(); // Replace with real deserialization
location = new Location(loc.get(0), loc.get(1), loc.get(2), loc.get(3));
// ... more code
我该怎么做呢?
3条答案
按热度按时间wribegjk1#
Java支持Custom Serialization。请阅读自定义默认协议一节。
引述如下:
然而,有一个奇怪而巧妙的解决方案。通过使用序列化机制的内置特性,开发人员可以通过在类文件中提供两个方法来增强正常的过程。这些方法是:
在此方法中,您可以根据需要将其序列化为其他形式,例如您所演示的Location的ArrayList、JSON或其他数据格式/方法,然后将其重新构造回readObject()
在您的示例中,添加以下代码:
dz6r00yl2#
类似于@莫莫的答案,但没有使用列表和自动装箱的int值,这将使它更加紧凑。
mnowg1ta3#
如果必须是Java序列化,我所知道的唯一方法是在所有引用
Location
示例的类中重新定义readObject()
和writeObject()
,如莫莫的答案所示。注意,这将不允许您序列化Location[]
,并要求您将代码中出现的所有Collection<Location>
子类化。此外,它要求类型为Location
的字段被标记为 transient ,这将排除它们的定义被写入串行化流,从而可能妨碍对不兼容类改变的检测。一个更好的方法是简单地重写
ObjectOutputStream.writeObject
。唉,那个方法是final
。你可以重写ObjectOutputStream.writeObjectOverride()
,但是那个方法不能委托默认实现ObjectOutputStream.writeObject0()
,因为那个方法是private
。当然,你可以使用反射调用私有方法,但是...所以我建议验证一下你的约束,一定要Java序列化吗,真的可以不修改类
Location
的定义吗?如果您有
Location
类的源代码,那么添加implements Serializable
并将其添加到您的类路径中是非常简单的。是的,无论何时升级库,您都必须再次执行此操作,但它可能比替代方法更好...