简体   繁体   English

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

[英]In java, is it possible to add the Serializable interface to class that doesn't have it at runtime?

There is a class I want to serialize, and it implements Serializable, but one of the objects it contains does not implement Serializable. 有一个我想序列化的类,它实现了Serializable,但它包含的一个对象没有实现Serializable。

Is there a way to modify the class at runtime to make it implement the Serializable interface so I can serialize it? 有没有办法在运行时修改类以使其实现Serializable接口,以便我可以序列化它? I can't change it at compile time because its a third party library. 我无法在编译时更改它,因为它是第三方库。

Maybe I would have to use some sort of bytecode writer or something? 也许我将不得不使用某种字节码编写器或什么?

EDIT: Both the containing class and contained class are in the 3rd party library so I don't think i can mark something as transient. 编辑:包含类和包含类都在第三方库中,所以我不认为我可以标记为瞬态。 The containing class is marked as serializable, but it contains an object that is not. 包含的类标记为可序列化,但它包含的对象不是。

I'm fine with writing a custom serialization method for the class, not sure how I would do this though, would I have to use reflection to get the values of the private variables? 我为这个类编写自定义序列化方法很好,但不知道我会怎么做,我是否必须使用反射来获取私有变量的值?

Reading the javadoc for Serializable, I see: 阅读Serializable的javadoc,我看到:

Classes that require special handling during the serialization and deserialization process must implement special methods with these exact signatures: 在序列化和反序列化过程中需要特殊处理的类必须使用这些精确签名实现特殊方法:

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

which you could use to manually serialize the uncooperative fields. 您可以使用它来手动序列化不合作的字段。 You could look into using ASM, but it seems hard to believe that it is a maintainable solution. 你可以考虑使用ASM,但似乎很难相信它是一个可维护的解决方案。

Fields can be skipped using the transient modifier. 可以使用transient修饰符跳过字段。 Additional data can be added to the stream by providing readObject and writeObject methods. 可以通过提供readObjectwriteObject方法将其他数据添加到流中。 Classes can be subclassed to make them serialisable (though you will need to manage the superclass data), or use a serial proxy (see Effective Java). 可以对类进行子类化以使其可序列化(尽管您需要管理超类数据),或使用串行代理(请参阅Effective Java)。

First of all, do you really need to do this? 首先,你真的需要这样做吗? Maybe the class in the third-party library is not serializable by design. 也许第三方库中的类不可设计序列化。 Even if it's just an omission rather than a deliberate decision, it's easy enough to write a custom serialization method in a helper class. 即使它只是一个遗漏而不是刻意的决定,在辅助类中编写自定义序列化方法也很容易。 If you have to do this though (like I had to, for something similar). 如果你必须这样做(就像我必须这样做的东西)。 Take a look at Javassist . 看看Javassist You can do something like this: 你可以这样做:

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

EDIT: You can use a third-party Serialization API like XStream instead of doing all the dirty work yourself. 编辑:您可以使用第三方序列化API,如XStream,而不是自己做所有脏工作。

If a class is not marked as Serializable that might be of good reasons (take database connections as an example). 如果一个类没有标记为Serializable,那可能是有充分理由的(以数据库连接为例)。 So first of all make your self clear if you really need to serialize that object as well. 因此,如果您确实需要序列化该对象,首先要清楚自己。 If you just need to serialize the surrounding object you may consider marking the contained object as transient. 如果只需要序列化周围的对象,可以考虑将包含的对象标记为瞬态。

You could use java.lang.reflect.Proxy to add the Serializable interface to object instances over which you have no life-cycle control (ie can't subcalass them) and get them serialized this way. 您可以使用java.lang.reflect.Proxy将Serializable接口添加到您没有生命周期控制的对象实例(即不能对它们进行子类化)并以这种方式对它们进行序列化。 But then you would still not be able to read them back without another hack (ie introducing a surrogate class). 但是如果没有另一个黑客(即引入代理类),你仍然无法阅读它们。

I'd recommend to look for an alternative to the Java Serializable mechanism in general. 我建议一般寻找Java Serializable机制的替代方案。 It's pretty much broken by design in several ways. 它在很多方面都被设计破坏了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM