← Back to Advanced Java Course | Chapter 11: Advanced & Security | Lesson 15 of 19

Java Serialization Advanced

Advanced Serialization

Serialization converts an object's in-memory state into a byte stream so it can be saved to a file or transmitted over a network and later reconstructed. For a class to support this, it must implement the marker interface Serializable, telling the JVM it's safe to serialize.

Example: Advanced Serialization

java
import java.io.*;
public class Main {
	static class User implements Serializable { // marker interface -- tells the JVM it's safe to serialize
		String name = "Riya";
	}
	public static void main(String[] args) throws Exception {
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		new ObjectOutputStream(bos).writeObject(new User());
		System.out.println("Serialized to " + bos.size() + " bytes");
	}
}

The transient Keyword

Applying the transient keyword to a field tells the serialization process to skip it entirely, which is exactly what you want for sensitive data (like a password field) or derived values that shouldn't be persisted or sent over the wire in a serialized form.

Example: The transient Keyword

java
import java.io.*;
public class Main {
	static class User implements Serializable {
		String name = "Riya";
		transient String password = "secret"; // skipped entirely during serialization
	}
	public static void main(String[] args) throws Exception {
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		new ObjectOutputStream(bos).writeObject(new User());
		ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
		User restored = (User) in.readObject();
		System.out.println(restored.name + " " + restored.password); // password is null after restore
	}
}

serialVersionUID

serialVersionUID is a static final long constant used to verify, at deserialization time, that the incoming byte stream actually matches the version of the class currently loaded. Without an explicit one, a class change can silently break deserialization of previously-saved data.

Example: serialVersionUID

java
import java.io.*;
public class Main {
	static class User implements Serializable {
		static final long serialVersionUID = 1L; // verified against the byte stream at deserialization
		String name = "Riya";
	}
	public static void main(String[] args) {
		System.out.println("serialVersionUID = " + User.serialVersionUID);
	}
}

Custom Serialization

You can override the default serialization behavior by defining private writeObject() and readObject() methods inside your Serializable class, giving you manual control to handle fields that need custom encoding logic rather than the default field-by-field approach.

Example: Custom Serialization

java
import java.io.*;
public class Main {
	static class User implements Serializable {
		String name = "Riya";
		private void writeObject(ObjectOutputStream out) throws IOException {
			out.defaultWriteObject();
			out.writeObject(name.toUpperCase()); // custom encoding logic
		}
	}
	public static void main(String[] args) throws Exception {
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		new ObjectOutputStream(bos).writeObject(new User());
		System.out.println("Custom writeObject() ran, " + bos.size() + " bytes written");
	}
}

Externalizable Interface

The Externalizable interface extends Serializable but hands you complete, manual control over the entire serialization process via writeExternal() and readExternal(), rather than relying on Java's default reflective serialization mechanism at all.

Example: Externalizable Interface

java
import java.io.*;
public class Main {
	static class User implements Externalizable {
		String name = "Riya";
		public User() {}
		public void writeExternal(ObjectOutput out) throws IOException {
			out.writeUTF(name); // fully manual control, no default reflective serialization
		}
		public void readExternal(ObjectInput in) throws IOException {
			name = in.readUTF();
		}
	}
	public static void main(String[] args) throws Exception {
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		new ObjectOutputStream(bos).writeObject(new User());
		System.out.println("Externalizable wrote " + bos.size() + " bytes manually");
	}
}

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.