Externalization example in Java

The Externalizable interface provides the necessary means for implementing a custom serialization mechanism.

Implementing the Externalizable interface means that we must override writeExternal() and readExternal() methods. These methods will be called when you serialize or deserialize a particular instance or object.

The difference between Serialization and Externalization is that when we implement the Serializable interface we do not need to implement any method; so the serialization takes place automatically.

Even if we want to implement our own serialization mechanism by implementing the Serializable interface (yes it is also possible by defining writeObject() and readObject() methods) we don’t need to override or implement any method.

Serialization uses certain default behaviors to store and later recreate the object. You may specify in what order or how to handle references and complex data structures, but eventually it comes down to using the default behavior for each primitive data field.

Externalization is used in the rare cases that you really want to store and rebuild your object in a completely different way and without using the default serialization mechanisms for data fields. For example, imagine that you had your own unique encoding and compression scheme.

In the below example class, when we are implementing the Externalizable interface we must also define a default constructor otherwise serialization will be failed.

public class User implements Externalizable {
        private String username;
        private String email;

        public User(){
        }

        public User(String username, String email) {
            this.username = username;
            this.email = email;
        }

        public String getUsername() {
            return username;
        }

        public String getEmail() {
            return email;
        }

        @Override
        public void writeExternal(ObjectOutput out) throws IOException {
            out.writeObject(username);
            out.writeObject(email);
        }

        @Override
        public void readExternal(ObjectInput in) throws IOException,
            ClassNotFoundException {
            username = (String) in.readObject();
            email = (String) in.readObject();
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((email == null) ? 0 : email.hashCode());
            result = prime * result
                    + ((username == null) ? 0 : username.hashCode());
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            User other = (User) obj;
            if (email == null) {
                if (other.email != null)
                    return false;
            } else if (!email.equals(other.email))
                return false;
            if (username == null) {
                if (other.username != null)
                    return false;
            } else if (!username.equals(other.username))
                return false;
            return true;
        }
    }

In the above Externalization example class we have overridden writeExternal() and readExternal() methods for implementing custom serialization of objects.

We have also overridden equals() and hashCode() methods to check for equality of two objects.

Thanks for reading.

Leave a Reply

Your email address will not be published. Required fields are marked *