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

时间:2010-01-22 00:34:09

标签: java serialization

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

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

也许我不得不使用某种字节码编写器?

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

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

5 个答案:

答案 0 :(得分:5)

读取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,但似乎很难相信它是一种可维护的解决方案。

答案 1 :(得分:3)

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

答案 2 :(得分:1)

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

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

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

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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

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