0

Lets us say my class MyClass has 10 variables. By marking the class with Serializable we serialize all the 10 variables.

My question is is there any way to serialize only some of these variables, let us say 5 only?

I know it can be done by marking the variables as transient. But I want to know if there is any other way to do that than using transient keyword.

Konstantin Yovkov
  • 62,134
  • 8
  • 100
  • 147
Tarun Deep Attri
  • 8,174
  • 8
  • 41
  • 56
  • Why do you need another way? Either way, you can take the entire process into your hand if you want to by creating a `readObject()`/`writeObject()` method. – biziclop Aug 04 '15 at 10:45
  • either you use transient or you make fields static because static variables are not saved anyway during serialization. – unique_ptr Aug 04 '15 at 10:46

3 Answers3

3

If your class implements the Externalizable interface, then you will have better control of how the object will be serialized.

Note that, unlike Serializable, the Externalizable interface is not a marker one and you will need to implement the readExternal() and writeExternal() methods, where you can actually pick programmatically which class members to be serialized and how de-serialization will be done.

More info:

Community
  • 1
  • 1
Konstantin Yovkov
  • 62,134
  • 8
  • 100
  • 147
0

Java supports Custom Serialization. Read the section Customize the Default Protocol.

There is, however, a strange yet crafty solution. By using a built-in feature of the serialization mechanism, developers can enhance the normal process by providing two methods inside their class files. Those methods are:

private void writeObject(ObjectOutputStream out) throws IOException;

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException;

Community
  • 1
  • 1
Ankush soni
  • 1,439
  • 1
  • 15
  • 30
0

An option when you want to customize serialization is to use serialization proxies: instead of your "real" object you create a substitute that is serialized instead. The serialization framework uses the writeReplace()/readResolve() methods, which allow you to do exactly this.

This is roughly what it looks like:

public class Foo implements Serializable {
    private final String bar;
    private final String baz;

    private static class FooProxy implements Serializable {
        private final String barBaz;

        private FooProxy(Foo foo) {
           this.barBaz = foo.bar + "|" + foo.baz; //don't do this for real
        }

        private Object readResolve() {
           String [] arr = this.barBaz.split( "|" );
           return new Foo(arr[0], arr[1]);
        }   

    }

    private Object writeReplace() {
        return new FooProxy(this);
    }

    // this method is required to stop a maliciously constructed serialized form to be deserialized
    private void readObject(ObjectInputStream ois) throws InvalidObjectException {
       throw new InvalidObjectException( "Use a proxy." );
    }

}

So every time Foo is to be serialized, it is replaced with a FooProxy object that has completely different fields, and every time FooProxy is deserialized, it's replaced with a corresponding Foo.

The advantage of this technique is that you can separate the serialized form from the internal representation completely, allowing you to change the internal representation arbitrarily, so long as it can be rebuilt from the serialized form.

biziclop
  • 48,926
  • 12
  • 77
  • 104