Java > Java Input/Output (I/O) > Serialization and Deserialization > ObjectInputStream and ObjectOutputStream
Serialization and Deserialization with Object Streams
This example demonstrates how to serialize and deserialize Java objects using `ObjectOutputStream` and `ObjectInputStream`. Serialization converts an object into a byte stream, which can be stored or transmitted, and deserialization reconstructs the object from the byte stream.
Introduction to Serialization
Serialization is the process of converting an object's state into a byte stream. Deserialization is the reverse process, reconstructing the object from the byte stream. These processes are crucial for tasks like saving object states to disk, transmitting objects over a network, or caching objects.
The `Serializable` Interface
For an object to be serializable, its class must implement the `java.io.Serializable` interface. This interface is a marker interface, meaning it doesn't declare any methods. It signals to the JVM that instances of the class can be serialized. Any fields you don't want to be serialized should be marked as `transient`.
Person Class (Serializable)
This `Person` class implements `Serializable`. The `secret` field is marked as `transient`, meaning it won't be serialized. When the `Person` object is deserialized, the `secret` field will be null (or its default value for its type).
import java.io.Serializable;
public class Person implements Serializable {
private String name;
private int age;
private transient String secret;
public Person(String name, int age, String secret) {
this.name = name;
this.age = age;
this.secret = secret;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public String getSecret() {
return secret;
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + ", secret='" + secret + "'}";
}
}
Serialization Example
This code demonstrates both serialization and deserialization. First, a `Person` object is created. Then: 1. **Serialization:** A `FileOutputStream` is created to write to the file "person.ser". An `ObjectOutputStream` is wrapped around the `FileOutputStream` to enable object serialization. The `writeObject()` method of `ObjectOutputStream` serializes the `person` object to the file. 2. **Deserialization:** A `FileInputStream` is created to read from the file "person.ser". An `ObjectInputStream` is wrapped around the `FileInputStream` to enable object deserialization. The `readObject()` method of `ObjectInputStream` deserializes the object from the file. The result is cast back to a `Person` object. The output will show the serialized message and then the deserialized `Person` object. Note that the `secret` field will be `null` in the deserialized object because it was marked as `transient`.
import java.io.*;
public class SerializationExample {
public static void main(String[] args) {
Person person = new Person("Alice", 30, "MySecret");
String filename = "person.ser";
// Serialization
try (FileOutputStream fileOut = new FileOutputStream(filename);
ObjectOutputStream out = new ObjectOutputStream(fileOut)) {
out.writeObject(person);
System.out.println("Serialized data is saved in " + filename);
} catch (IOException i) {
i.printStackTrace();
}
// Deserialization
try (FileInputStream fileIn = new FileInputStream(filename);
ObjectInputStream in = new ObjectInputStream(fileIn)) {
Person deserializedPerson = (Person) in.readObject();
System.out.println("Deserialized Person: " + deserializedPerson);
} catch (IOException i) {
i.printStackTrace();
} catch (ClassNotFoundException c) {
System.out.println("Person class not found");
c.printStackTrace();
}
}
}
Concepts Behind the Snippet
The core concepts are:
Real-Life Use Case
Serialization is used in several scenarios:
Best Practices
Interview Tip
Be prepared to explain the difference between serialization and deserialization. Understand the purpose of the `Serializable` interface and the `transient` keyword. Be aware of the potential security risks associated with deserialization and how to mitigate them.
When to use them
Use serialization/deserialization when you need to:
Consider alternatives like JSON or Protocol Buffers for inter-system communication and data exchange, especially when dealing with different programming languages.
Memory Footprint
The memory footprint of a serialized object depends on the size of the object's data and the serialization format. Serialization can increase the size of the data due to metadata overhead. Transient fields reduce the memory footprint of the serialized data. When deserializing, the JVM needs enough memory to reconstruct the entire object graph.
Alternatives
Alternatives to Java serialization include:
Pros
Pros of Java Serialization:
Cons
Cons of Java Serialization:
FAQ
-
What happens if a class doesn't implement `Serializable`?
If you try to serialize an object of a class that doesn't implement `Serializable`, you'll get a `NotSerializableException`. -
What is `serialVersionUID` and why is it important?
`serialVersionUID` is a unique identifier for a serializable class. It's used during deserialization to verify that the serialized data is compatible with the current class version. If the `serialVersionUID` of the serialized object doesn't match the `serialVersionUID` of the class, an `InvalidClassException` is thrown. It's crucial for maintaining compatibility across different versions of a class. -
What is the purpose of the `transient` keyword?
The `transient` keyword is used to prevent a field from being serialized. Transient fields are not saved as part of the object's serialized state. They're typically used for fields that are derived, contain sensitive information, or should not be persisted.