在java中,如何序列化未标记为可序列化的类?

2022-09-03 06:35:34

第三方库中有一个特定的类,我想序列化它。我该怎么做?

我假设我必须编写一个方法,该方法接收类的对象并使用反射来获取私有成员值。然后,对于反序列化,我将使用反射将值放回原处。

这行得通吗?有没有更简单的方法?


答案 1

您可以只使用实现 Serializable 的传输对象,并且具有与第三方对象相同的字段。让传输对象实现一个返回原始第三方类的对象的方法,您就完成了:

伪代码:

class ThirdParty{

    int field1;
    int field2;
}

class Transfer implements Serializable{

    int field1;
    int field2;

    /* Constructor takes the third party object as 
       an argument for copying the field values.
       For private fields without getters 
       use reflection to get the values */
    Transfer (ThirdParty orig){
       this.field1=orig.field1;
       this.field2=orig.field2;
    }
 
    ThirdParty getAsThirdParty(){
        ThirdParty copy=new ThirdParty();
        copy.field1=this.field1;
        copy.field2=this.field2;
        return copy;
    }
    
    /* override these methods for custom serialization */
    void writeObject(OutputStream sink);
    void readObject(InputStream src);
}

只要获得任何特殊成员对象,就必须确保正确序列化成员。

或者,如果第三方类不是最终的,你可以扩展它,让它实现可序列化,并编写你自己的 writeObject 和 readObject 方法。

查看此处了解一些序列化信息:


答案 2

您需要将其包装到执行序列化的内容中。

理想情况下,第三方类支持某些其他形式的序列化,例如 XML 序列化(基于 Bean 属性)。如果没有,你必须自己滚动。这是否涉及反射或仅涉及 getter、setter 和构造函数取决于类。

在任何情况下,包装器都会将对象转换为byte[]或String或其他内容,并将其写入序列化输出。在反序列化时,它会从该数据重建对象。

包装器必须实现的两种方法是

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