Marker Interfaces in Java
1.1 What is a Marker Interface?
A Marker Interface is an interface that does not contain any methods or fields. It is used to provide metadata or special information to the JVM, compiler, or frameworks.
A marker interface is also called a tagging interface because it “marks” a class with a specific capability.
Example
public interface Serializable {
}The Serializable interface does not define any methods. Still, when a class implements it, the JVM understands that the objects of that class can be serialized.
1.2 Why Do We Need Marker Interfaces?
Marker interfaces are used to indicate that a class has a special behavior.
For example:
class Employee implements Serializable {
private int id;
private String name;
}Here, Employee is marked as serializable. The JVM checks whether the object implements Serializable before allowing serialization.
If the class does not implement Serializable, the JVM throws:
1.3 Common Marker Interfaces in Java
1. Serializable
The Serializable interface is used to allow an object to be converted into a byte stream.
Package:
Example:
import java.io.Serializable;class Employee implements Serializable {
private int id;
private String name; public Employee(int id, String name) {
this.id = id;
this.name = name;
}
}
Purpose:
- Allows object serialization.
- Used in file storage, caching, distributed systems, and session replication.
2. Cloneable
The Cloneable interface indicates that an object can be cloned using the clone() method.
Package:
Example:
class Student implements Cloneable {
int id;
String name;Student(int id, String name) {
this.id = id;
this.name = name;
} protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}public class CloneExample {
public static void main(String[] args) throws CloneNotSupportedException {
Student s1 = new Student(101, "Anand");
Student s2 = (Student) s1.clone(); System.out.println(s2.id);
System.out.println(s2.name);
}
}
If a class does not implement Cloneable and we call clone(), Java throws:
CloneNotSupportedException3. Remote
The Remote interface is used in Java RMI.
Package:
java.rmi.RemoteIt marks an object whose methods can be called from another JVM.
Example:
import java.rmi.Remote;
import java.rmi.RemoteException;public interface PaymentService extends Remote {
void processPayment() throws RemoteException;
}1.4 Role and Significance of Marker Interfaces
Marker interfaces provide metadata to the Java runtime or frameworks.
They are useful for:
- Identifying special behavior.
- Enabling JVM-level operations.
- Allowing frameworks to apply special processing.
- Providing type safety.
- Avoiding accidental misuse of APIs.
Example:
if (object instanceof Serializable) {
System.out.println("Object can be serialized");
}1.5 How JVM Uses Marker Interfaces
The JVM checks whether a class implements a marker interface before performing specific operations.
Serializable Example
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("employee.ser"));
oos.writeObject(employee);Before writing the object, JVM checks whether the object implements Serializable.
If yes, serialization proceeds.
If no, JVM throws:
NotSerializableExceptionCloneable Example
When calling:
The JVM checks whether the object implements Cloneable.
If the class does not implement Cloneable, Java throws:
1.6 How Frameworks Use Marker Interfaces
Frameworks can use marker interfaces to identify classes that require special handling.
Example:
interface Auditable {
}class Order implements Auditable {
}A framework can check:
if (entity instanceof Auditable) {
System.out.println("Apply audit logic");
}This can be used for:
- Audit logging
- Security checks
- Caching
- Custom validation
- Special business processing
1.8 When to Use Marker Interfaces
Use marker interfaces when:
- You need type checking.
- You want to restrict method parameters to specific marked classes.
- You want compile-time safety.
- You need behavior similar to
SerializableorCloneable.
Example:
interface Exportable {
}class Report implements Exportable {
}public void exportData(Exportable exportable) {
System.out.println("Exporting data...");
}
2. Java Serialization and Deserialization
2.1 What is Serialization?
Serialization is the process of converting a Java object into a byte stream.
This byte stream can be:
- Saved to a file.
- Sent over a network.
- Stored in a database.
- Stored in cache.
- Transferred between JVMs.
2.2 What is Deserialization?
Deserialization is the process of converting a byte stream back into a Java object.
In simple terms:
Serialization : Object -> Byte Stream
Deserialization : Byte Stream -> Object2.3 Why Serialization is Used
Serialization is commonly used in:
- File storage
- Distributed applications
- Caching
- HTTP session replication
- Messaging systems
- Remote method invocation
- Deep copy scenarios
2.4 Serializable Interface
To make a class serializable, it must implement Serializable.
Example:
import java.io.Serializable;class Employee implements Serializable {
private int id;
private String name; public Employee(int id, String name) {
this.id = id;
this.name = name;
} public void display() {
System.out.println(id + " - " + name);
}
}
2.5 Serialization Example
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;class Employee implements Serializable {
private int id;
private String name; public Employee(int id, String name) {
this.id = id;
this.name = name;
}
}public class SerializationExample {
public static void main(String[] args) {
Employee employee = new Employee(101, "Anand"); try {
FileOutputStream fos = new FileOutputStream("employee.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(employee); oos.close();
fos.close(); System.out.println("Object serialized successfully"); } catch (Exception e) {
e.printStackTrace();
}
}
}
2.6 Deserialization Example
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.io.Serializable;class Employee implements Serializable {
private int id;
private String name; public void display() {
System.out.println(id + " - " + name);
}
}public class DeserializationExample {
public static void main(String[] args) {
try {
FileInputStream fis = new FileInputStream("employee.ser");
ObjectInputStream ois = new ObjectInputStream(fis); Employee employee = (Employee) ois.readObject(); employee.display(); ois.close();
fis.close(); } catch (Exception e) {
e.printStackTrace();
}
}
}
2.7 Role of serialVersionUID
serialVersionUID is a unique version identifier for a serializable class.
It is used during deserialization to verify that the sender and receiver classes are compatible.
Example:
private static final long serialVersionUID = 1L;Full example:
import java.io.Serializable;class Employee implements Serializable {
private static final long serialVersionUID = 1L; private int id;
private String name;
}
2.8 Why serialVersionUID is Important
During serialization, Java stores the serialVersionUID along with the object data.
During deserialization, Java compares:
serialVersionUIDfrom the serialized objectserialVersionUIDfrom the current class
If both values match, deserialization succeeds.
If they do not match, Java throws:
InvalidClassException2.9 What Happens If serialVersionUID is Not Declared?
If we do not declare serialVersionUID, Java automatically generates one based on class details such as:
- Class name
- Fields
- Methods
- Constructors
- Access modifiers
Problem:
Small changes in the class may generate a different serialVersionUID, causing deserialization failure.
Therefore, it is recommended to explicitly declare it.
2.10 Example of serialVersionUID Issue
Version 1:
class Employee implements Serializable {
private int id;
private String name;
}Object is serialized using this class.
Later, the class is changed.
Version 2:
class Employee implements Serializable {
private int id;
private String name;
private double salary;
}If Java generates a different serialVersionUID, deserialization may fail.
Error:
java.io.InvalidClassExceptionBetter approach:
class Employee implements Serializable {
private static final long serialVersionUID = 1L; private int id;
private String name;
private double salary;
}2.11 transient Keyword
The transient keyword is used to prevent a field from being serialized.
Example:
class User implements Serializable {
private String username;
private transient String password;
}Here, password will not be saved during serialization.
2.12 Why transient is Used
The transient keyword is commonly used for:
- Passwords
- Security tokens
- Temporary values
- Cache values
- Derived fields
- Non-serializable fields
- Sensitive data
2.13 transient Example
import java.io.*;class User implements Serializable {
private static final long serialVersionUID = 1L; private String username;
private transient String password; public User(String username, String password) {
this.username = username;
this.password = password;
} public void display() {
System.out.println("Username: " + username);
System.out.println("Password: " + password);
}
}public class TransientExample {
public static void main(String[] args) {
User user = new User("anand", "secret123"); try {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.ser"));
oos.writeObject(user);
oos.close(); ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.ser"));
User deserializedUser = (User) ois.readObject();
ois.close(); deserializedUser.display(); } catch (Exception e) {
e.printStackTrace();
}
}
}
Output:
Username: anand
Password: nullSince password is marked as transient, it is not serialized. During deserialization, it gets the default value.
2.14 Default Values for transient Fields
2.15 Impact on Object State During Serialization
Serialization stores the object state at the time of serialization.
Get Java Codeex’s stories in your inbox
Join Medium for free to get updates from this writer.
Example:
Employee emp = new Employee(101, "Anand");When serialized, the values of id and name are stored.
If the object changes later, the serialized file still contains the old state.
Example:
Employee emp = new Employee(101, "Anand");
serialize(emp);emp.setName("Kumar");The serialized object still contains:
101 - AnandUnless it is serialized again.
2.16 What is Serialized and What is Not Serialized?
Serialized
- Non-static fields
- Non-transient fields
- Serializable object references
Not Serialized
- Static fields
- Transient fields
- Methods
- Constructors
- Runtime stack information
2.17 Static Fields and Serialization
Static fields belong to the class, not the object. Therefore, static fields are not serialized.
Example:
class Employee implements Serializable {
static String company = "ABC";
private int id;
private String name;
}Only id and name are serialized.
The value of company comes from the current class at runtime.
2.18 Object References During Serialization
If a serialized object contains another object reference, the referenced object must also be serializable.
Example:
class Address implements Serializable {
String city;
}class Employee implements Serializable {
int id;
String name;
Address address;
}Here, both Employee and Address must implement Serializable.
If Address does not implement Serializable, Java throws:
NotSerializableException2.19 Serialization Best Practices
- Always declare
serialVersionUID. - Do not serialize sensitive data.
- Use
transientfor passwords, tokens, and temporary data. - Ensure all referenced objects are serializable.
- Avoid serialization for long-term storage.
- Prefer JSON, XML, Avro, or Protobuf for distributed systems.
- Be careful when changing class structure.
- Avoid serializing large object graphs.
- Validate objects after deserialization.
- Be careful with deserialization security risks.
3. Externalization vs Serialization
3.1 What is Externalization?
Externalization is an advanced form of serialization where the class itself controls what data should be serialized and deserialized.
To use externalization, a class must implement:
java.io.ExternalizableThe Externalizable interface contains two methods:
void writeExternal(ObjectOutput out) throws IOException;void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;3.2 Externalizable Interface
public interface Externalizable extends Serializable {
void writeExternal(ObjectOutput out) throws IOException; void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;
}Important point:
Externalizable extends Serializable.
So, every externalizable class is also serializable.
3.3 Externalization Example
import java.io.*;class Employee implements Externalizable {
private int id;
private String name;
private double salary; public Employee() {
// Public no-argument constructor is required
} public Employee(int id, String name, double salary) {
this.id = id;
this.name = name;
this.salary = salary;
} @Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(id);
out.writeObject(name);
out.writeDouble(salary);
} @Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
id = in.readInt();
name = (String) in.readObject();
salary = in.readDouble();
} public void display() {
System.out.println(id + " - " + name + " - " + salary);
}
}public class ExternalizationExample {
public static void main(String[] args) {
Employee employee = new Employee(101, "Anand", 75000); try {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("employee_ext.ser"));
oos.writeObject(employee);
oos.close(); ObjectInputStream ois = new ObjectInputStream(new FileInputStream("employee_ext.ser"));
Employee emp = (Employee) ois.readObject();
ois.close(); emp.display(); } catch (Exception e) {
e.printStackTrace();
}
}
}
3.4 Public No-Argument Constructor Requirement
For externalization, the class must have a public no-argument constructor.
Example:
public Employee() {
}During deserialization, Java first creates the object using the public no-argument constructor and then calls:
readExternal()If the public no-argument constructor is missing, Java throws:
InvalidClassException3.5 Custom Control Over Object Persistence
Serialization automatically saves all non-static and non-transient fields.
Externalization gives full control.
Example:
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(id);
out.writeObject(name);
}Here, only id and name are serialized. salary is ignored.
During deserialization:
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
id = in.readInt();
name = (String) in.readObject();
}The ignored field gets the default value.
3.6 Serialization vs Externalization
3.7 Constructor Behavior Difference
Serialization
During deserialization, the constructor of the serializable class is not called.
class Employee implements Serializable {
public Employee() {
System.out.println("Constructor called");
}
}During deserialization, this constructor will not execute.
Externalization
During deserialization, the public no-argument constructor is called.
class Employee implements Externalizable {
public Employee() {
System.out.println("Constructor called");
}
}During deserialization, this constructor executes first, then readExternal() is called.
3.8 Performance Considerations
Serialization Performance
Default serialization is easy to use but can be slower because:
- JVM uses reflection.
- It stores class metadata.
- It serializes the object graph automatically.
- It may serialize more data than required.
- It has less control over output size.
Externalization Performance
Externalization can be faster because:
- Developer controls exactly what is written.
- Unnecessary fields can be skipped.
- Data can be written in compact format.
- Object graph can be controlled manually.
However, externalization can also be risky if not implemented carefully.
3.9 When Externalization Gives Better Performance
Externalization is useful when:
- Object has many fields but only a few need to be persisted.
- Object contains large temporary data.
- Serialization format needs to be compact.
- Performance is critical.
- You want full control over object state.
- You want backward compatibility handling manually.
Example:
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(id);
out.writeObject(name);
}This is faster than serializing the full object if the object has many unnecessary fields.
3.10 Disadvantages of Externalization
Externalization has some drawbacks:
- More boilerplate code.
- Developer must maintain serialization order.
- Mistakes can cause data corruption.
- Public no-argument constructor is mandatory.
- More difficult to maintain.
- Less suitable for simple objects.
3.11 Important Rule: Order Must Match
The order of writing and reading must be the same.
Correct:
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(id);
out.writeObject(name);
}public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
id = in.readInt();
name = (String) in.readObject();
}Incorrect:
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(id);
out.writeObject(name);
}public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
name = (String) in.readObject();
id = in.readInt();
}This can cause runtime errors or incorrect data.
3.12 When to Use Serialization
Use Serialization when:
- You want a simple object persistence mechanism.
- You do not need custom control.
- Object structure is simple.
- Performance is not a major concern.
- You are working with Java-only systems.
3.13 When to Use Externalization
Use Externalization when:
- You need full control over serialization.
- You want to improve performance.
- You want to skip unnecessary fields.
- You want custom object reconstruction.
- You want a compact serialized format.
3.14 Real-Time Use Cases
Serialization Use Cases
- HTTP session replication
- Distributed caching
- Saving object state to fil
- Deep cloning
- Messaging between Java applications
Externalization Use Cases
- High-performance object persistence
- Custom binary format
- Large object optimization
- Backward-compatible object reading
- Selective field serialization
Interview Questions and Answers
Q1. What is a marker interface?
A marker interface is an interface without methods or fields. It is used to mark a class with special capability. Examples are Serializable, Cloneable, and Remote.
Q2. Why is Serializable called a marker interface?
Because it does not contain any methods. It only marks a class as eligible for serialization.
Q3. What happens if a class does not implement Serializable?
If we try to serialize an object that does not implement Serializable, Java throws:
NotSerializableException
Q4. What is serialVersionUID?
serialVersionUID is a unique version identifier used during deserialization to verify whether the serialized object and current class are compatible.
Q5. What happens if serialVersionUID does not match?
Java throws:
InvalidClassException
Q6. What is the use of transient keyword?
The transient keyword prevents a field from being serialized.
Q7. Are static variables serialized?
No. Static variables are not serialized because they belong to the class, not the object.
Q8. What is Externalizable?
Externalizable is an interface that allows the developer to control the serialization and deserialization process manually using writeExternal() and readExternal().
Q9. Difference between Serializable and Externalizable?
Serializable is a marker interface where JVM controls serialization. Externalizable gives full control to the developer through writeExternal() and readExternal() methods.
Q10. Is constructor called during deserialization?
For Serializable, constructor is not called during deserialization.
For Externalizable, public no-argument constructor is called during deserialization.
Summary
Marker interfaces are used to mark classes with special capabilities. Serializable and Cloneable are common examples.
Serialization converts an object into a byte stream, while deserialization converts the byte stream back into an object. serialVersionUID helps maintain class version compatibility. The transient keyword prevents sensitive or unnecessary fields from being serialized.
Externalization is a more advanced form of serialization that gives complete control to the developer. It can improve performance but requires more careful implementation.
Use Serializable for simple object persistence and Externalizable when you need custom control and performance optimization.
I can also convert this into a downloadable Word/PDF document or prepare it as interview notes with diagrams and short answers.

![Spring Boot 3 + Spring Security 6 With JWT Authentication and Authorization [New 2024]](https://webproxy.poorya-velaei-d67.workers.dev/https://miro.medium.com/v2/resize:fit:1358/format:webp/1*vsCw_bg8325pbPjZ88UMGg.png)







