The serialization is the conversion of an object’s state into a format that can be stored or transmitted.
When a program ends, the objects it held in memory cease to exist. If we want to preserve their data or send it to another system, we need to represent them in another format.
That process is called serialization.
What is serializing?
It is the process of converting an Object (which lives in memory and has a complex structure) into a linear sequence of bytes (zeros and ones).
- Serialize (Dehydrate): Object -> Bytes. (To save to a file or send over a network).
- Deserialize (Hydrate): Bytes -> Object. (Rebuild the original object).
Native serialization (Serializable)
Java has had a built-in mechanism for this since its inception. For an object to be “frozen”, its class must implement the java.io.Serializable interface.
Marker Interface:
If you look at the Serializable code, you’ll see that it is empty. It has no methods. It only serves as a “tag” to tell the Java Virtual Machine: “Hey, it’s allowed to convert objects of this class into bytes. I take responsibility.”
Practical example
Let’s save an object to a .ser file and then retrieve it.
Step 1: The Class
import java.io.Serializable;
public class Videojuego implements Serializable {
// Good practice to add this version ID to avoid errors when deserializing
private static final long serialVersionUID = 1L;
private String titulo;
private int nivel;
// ... constructor, getters and setters ...
}Step 2: Write (Serialize)
We use ObjectOutputStream.
Videojuego partida = new Videojuego("Super Mario", 5);
try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("partida.ser"))) {
out.writeObject(partida); // Converts the object's state to bytes
} catch (IOException e) { ... }Step 3: Read (Deserialize)
We use ObjectInputStream.
try (ObjectInputStream in = new ObjectInputStream(new FileInputStream("partida.ser"))) {
// Retrieve the object (we cast it)
Videojuego partidaCargada = (Videojuego) in.readObject();
System.out.println("Nivel recuperado: " + partidaCargada.getNivel());
} catch (IOException | ClassNotFoundException e) { ... }The transient keyword
Sometimes, there is data inside an object that we do not want to save.
- A password in plain text.
- An open database connection (it makes no sense to save it).
- A temporary calculated datum.
To prevent a field from being saved, we mark it as transient.
public class Usuario implements Serializable {
private String nombre; // Gets saved
private transient String password; // IS IGNORED. Will be null when read.
}The problem with native serialization
If it’s so easy, why did I tell you it is rarely used today?
- It’s Java-exclusive: A
.serfile generated by Java cannot be read by a program written in Python, JavaScript, or C#. It is a closed format. - It is fragile: If you save a
Videojuegoobject, and tomorrow you change the class (add a new field), when trying to read the old file, Java will throw anInvalidClassException. TheserialVersionUIDhelps control this, but it is painful to manage. - Security: Deserializing can execute code from the classes present in the process. Do not use
ObjectInputStreamwith untrusted data; if you must maintain this format, apply deserialization filters and a closed list of allowed types.
The modern alternative: JSON
Today, the world is connected. Java talks to websites (JS), AIs (Python), and mobile devices (Swift). We need a universal format.
The current standard is to serialize to JSON (plain text). Java SE does not include a general JSON converter. External libraries like Jackson or Gson are used for this purpose.
Example with Jackson
Notice how clean it is. And the result is a .json text file that anyone can read.
import com.fasterxml.jackson.databind.ObjectMapper;
// 1. Instantiate the mapper (the translator)
ObjectMapper mapper = new ObjectMapper();
Videojuego juego = new Videojuego("Zelda", 10);
// 2. Serialize (Java -> JSON)
// Creates a "juego.json" file with text: {"titulo":"Zelda", "nivel":10}
mapper.writeValue(new File("juego.json"), juego);
// 3. Deserialize (JSON -> Java)
Videojuego cargado = mapper.readValue(new File("juego.json"), Videojuego.class);