开发者

How do I serialize and deserialize in Java when I have a black box to convert to/from a byte array?

I have a class that is something like the following:

public class Foo {
  static开发者_开发技巧 byte[] convertToArray(Foo f);
  static Foo convertToFoo(byte[] ba);
}

How can I use convertToArray and convertToFoo to allow Foo to implement java.io.Serializable? The default serialization procedure doesn't seem like a good solution for my class because it would require changing a lot of other classes to implement Serializable. However, I already have a way to go to and from bytes, so there should be an easy way for Foo to implement serializable without having to declare all dependent members as Serializable. I suspect overriding readObject and writeObject is the way to go, but what is the correct way to do this, since these are instance methods with return type void?


Check out Externalizable, which is a subinterface of Serializable. Its readExternal and writeExternal methods delegate the serialization details to the programmer, which sounds appropriate in your case.

During deserialization (in your implementation of readExternal), you will need to use Foo.convertToFoo to convert the bytes from an ObjectInput to a Foo object, and then copy all of the state of that Foo object into this.

A snippet from the Javadoc that describes the semantics of Externalizable:

Only the identity of the class of an Externalizable instance is written in the serialization stream and it is the responsibility of the class to save and restore the contents of its instances. The writeExternal and readExternal methods of the Externalizable interface are implemented by a class to give the class complete control over the format and contents of the stream for an object and its supertypes. These methods must explicitly coordinate with the supertype to save its state. These methods supersede customized implementations of writeObject and readObject methods.


Assuming your class is final then you probably want to use a serial proxy (see Effective Java). Implement Serializable, but make readObject, readObjectNoData and writeObject throw an exception. Use writeReplace to produce a serialisable proxy object containing the binary data. In the proxy, use readResolve to create a Foo from the data.

public final class Foo implements Serializable {
    private static final long serialVersionUID = 42L;
    private static final ObjectStreamField[] serialPersistentFields = { }
    static byte[] convertToArray(Foo f) { ... }
    static Foo convertToFoo(byte[] ba) { ... }

    private void writeObject(
        ObjectOutputStream out {
    ) throws IOException {
        throw new NotSerializableException();
    }
    private void readObject(
        ObjectInputStream in
    ) throws IOException, ClassNotFoundException {
        throw new NotSerializableException();
    }
    private void readObjectNoData( 
    ) throws ObjectStreamException {
        throw new NotSerializableException();
    }
    private Object writeReplace() throws ObjectStreamException {
        return new FooSerialProxy(this);
    }
}

/* pp */ final class FooSerialProxy implements Serializable {
    private static final long serialVersionUID = 42L;
    private final byte[] data;
    /* pp */ FooSerialProxy(Foo foo) {
        this.data = Foo.convertToArray(foo);
    }
    private Object readResolve() throws ObjectStreamException {
        return Foo.convertToFoo(data);
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜