2015年11月9日星期一

如何序列化一个non serializable的类?

进行Spark开发时,经常会遇到这种问题?如何序列化一个没有实现Serializable接口的类呢?
以下将进行简单说明:Non Serializable记为A。

主要步骤:
0.使用一个外部类Outer将A作为一个成员变量,标记为@transient,且Outer能够通过getter或者其他方式访问A的状态;或者Outer继承A;
1.Outer实现Serializable接口,并且重写readObject和writeObject方法,实现定制化的序列化;
2.Outer在writeObject方法中,将A的状态进行序列化,并且readObject方法中,将A的状态读取出来,对A进行构造。
3.具体实现时,在writeObject方法中,首先调用defaultWriteObject方法,保存所有的non-transient成员,然后保存A的可序列化的状态;在readObject方法中,首先调用defaultReadObject方法,获取所有的non-transient成员,然后读取A的状态。

example:

public class App {

    int quantity;
    int count;

    public int getQuantity() {
        return quantity;
    }

    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }

    public App(int quantity, int count) {
        super();
        this.quantity = quantity;
        this.count = count;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

}

public class UnSerializeItem {

    private App nonSerializableProperty;

    public void setNonSerializableProperty(App nonSerializableProperty) {
        this.nonSerializableProperty = nonSerializableProperty;
    }

    public App getNonSerializableProperty() {
        return nonSerializableProperty;
    }
}

public class OuterItem extends UnSerializeItem implements Serializable{

    private static final long serialVersionUID = 1L;

    private int field;

    public int getField() {
        return field;
    }

    public void setField(int field) {
        this.field = field;
    }

    public OuterItem(int quantity, int count, int field) {
        setNonSerializableProperty(new App(quantity, count));
        this.field = field;
    }

    private void writeObject(java.io.ObjectOutputStream out)
            throws IOException {
        out.defaultWriteObject();
        out.writeInt(super.getNonSerializableProperty().getQuantity());
        out.writeInt(super.getNonSerializableProperty().getCount());
    }

    private void readObject(java.io.ObjectInputStream in)
            throws IOException, ClassNotFoundException {
        in.defaultReadObject();
        super.setNonSerializableProperty(new App(in.readInt(), in.readInt()));
    }
}

没有评论:

发表评论