在java中,是否可以将Serializable接口添加到在运行时没有它的类?

有一个我想序列化的类,它实现了Serializable,但它包含的其中一个对象没有实现Serializable。

有没有办法在运行时修改类以使其实现Serializable接口,以便我可以序列化它? 我无法在编译时更改它,因为它是第三方库。

也许我不得不使用某种字节码编写器或其他东西?

编辑:包含类和包含类都在第三方库中,所以我不认为我可以标记为瞬态。 包含的类标记为可序列化,但它包含的对象不是。

我为这个类编写自定义序列化方法很好,但不知道我会怎么做,我是否必须使用reflection来获取私有变量的值?

阅读Serializable的javadoc,我看到:

在序列化和反序列化过程中需要特殊处理的类必须使用这些精确签名实现特殊方法:

private void writeObject(java.io.ObjectOutputStream out) throws IOException private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException; private void readObjectNoData() throws ObjectStreamException; 

您可以使用它来手动序列化不合作的字段。 您可以考虑使用ASM,但似乎很难相信它是一个可维护的解决方案。

可以使用transient修改器跳过字段。 通过提供readObjectwriteObject方法,可以将其他数据添加到流中。 可以对类进行子类化以使其可序列化(尽管您需要管理超类数据),或使用串行代理(请参阅Effective Java)。

首先,你真的需要这样做吗? 也许第三方库中的类不可设计序列化。 即使这只是一个遗漏而不是刻意的决定,在辅助类中编写自定义序列化方法也很容易。 如果你必须这样做(就像我必须这样做的东西)。 看看Javassist 。 你可以这样做:

 ClassPool pool = ClassPool.getDefault(); CtClass cc = pool.get("mypackage.MyClass"); cc.addInterface(pool.get("java.io.Serializable")) 

编辑:你可以使用第三方序列化API,如XStream,而不是自己做所有的脏工作。

如果一个类没有被标记为Serializable,那可能是有充分理由的(以数据库连接为例)。 因此,如果您确实需要序列化该对象,首先要清楚自己。 如果只需要序列化周围的对象,可以考虑将包含的对象标记为瞬态。

您可以使用java.lang.reflect.Proxy将Serializable接口添加到您没有生命周期控制的对象实例(即不能对它们进行子类化)并以这种方式对它们进行序列化。 但是如果没有其他黑客(即引入代理类),你仍然无法阅读它们。

我建议一般寻找Java Serializable机制的替代方案。 它在很多方面都被设计破坏了。