Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Serialization Proxy Pattern Example

DZone's Guide to

Serialization Proxy Pattern Example

· Java Zone
Free Resource

Find your next Integration job at DZone Jobs. See jobs focused on integration, or create your profile and have the employers come to you!

There are books, which change your life immensely. One of such books is  "Effective Java" by  Joshua Bloch. Below you may find small experiment, which was inspired by Chapter 11 of this book - "Serialization".

Suppose that we have a class designed for inheritance, which is not  Serializable itself, and has no parameterless constructor, like in this example:
public class CumbersomePoint {

    private String name;

    private double x;

    private double y;

    protected CumbersomePoint(double x, double y, String name) {
        this.x = x;
        this.y = y;
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public double getX() {
        return x;
    }

    public double getY() {
        return y;
    }

    ...
}
Now when we extend this class, for example in following way:
public class ConvenientPoint extends CumbersomePoint implements Serializable {

    public ConvenientPoint(double x, double y, String name) {
        super(x, y, name);
    }

    ...
}
and try to serialize and then deserialize any of  ConvenientPoint instances, we'll quickly encounter beautiful InvalidClassException, complaining that there is no valid constructor. Situation looks kinda hopeless, until you apply technique known as  Serialization Proxy Pattern.

We will start by adding to the  ConvenientPoint class following inner class:
private static class SerializationProxy implements Serializable {

        private String name;

        private double x;

        private double y;

        public SerializationProxy(ConvenientPoint point) {
            this.name = point.getName();
            this.x = point.getX();
            this.y = point.getY();
        }

        private Object readResolve() {
            return new ConvenientPoint(x, y, name);
        }

    }
The  SerializationProxy class will represent the logical state of enclosing class instance. We will have to add also following method to  ConvenientPoint class:
   private Object writeReplace() {
        return new SerializationProxy(this);
    }

Now when the  ConvenientPoint instance will be serialized, it will nominate its replacement, thanks to  writeReplacemethod -  SerializationProxy instance will be serialized instead of  ConvenientPoint.

From the other side, when  SerializationProxy will be deserialized,  readResolve method usage will nominate its replacement, being  ConvenientPoint instance.

As you see, we've made  ConvenientPoint serializable, regardless of missing parameterless constructor of non-serializable parent class.

One more remark, at the end of this post - if you want to protect against breaking class invariants, enforced by the constructor, you may add following method to class using  Serialization Proxy Pattern ( ConvenientPoint in our example): 
   private void readObject(ObjectInputStream stream) throws InvalidObjectException {
        throw new InvalidObjectException("Use Serialization Proxy instead.");
    }
It will prevent deserialization of the enclosing class.

Find your next Integration job at DZone Jobs. See jobs focused on integration, or create your profile and have the employers come to you!

Topics:

Published at DZone with permission of Michal Jastak, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}