Skip to Content
Course content

97: Serialization Basics

Click on the "Edit" button in the top corner of the screen to edit your slide content.

What actually is serialization, and why would I use it?

Think of serialization as "freezing" an object. Normally, when your Java program stops running, every object in memory vanishes. But what if you're building something like a game and you want the player to be able to save their progress? You can't just save a reference to the object—that reference is just a memory address that will be meaningless the next time the app starts.

Serialization is the process of converting the state of an object into a byte stream. Once it's a stream of bytes, you can write it to a file, send it over a network, or store it in a database. Deserialization is just the reverse: taking those bytes and reconstructing the object back into the JVM's memory.

How do I actually make a class serializable?

Java makes this surprisingly simple, though it feels a bit like magic at first. You just have your class implement the Serializable interface. Now, here is the catch: Serializable is a "marker interface." It has no methods to implement. By adding it, you're essentially putting a sticky note on your class that tells the JVM, "Yes, I've vetted this class, and it's safe to turn into bytes."

Let's look at a PlayerProfile example. I'll show you how to write the object to a file using ObjectOutputStream:

import java.io.*;

public class PlayerProfile implements Serializable {
    public String username;
    public int level;
    public int experiencePoints;

    public PlayerProfile(String username, int level, int experiencePoints) {
        this.username = username;
        this.level = level;
        this.experiencePoints = experiencePoints;
    }
}

// To save this to a file:
public void savePlayer(PlayerProfile player) throws IOException {
    try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("savegame.ser"))) {
        oos.writeObject(player);
    }
}

What if there's data I don't want to save?

In a real project, you'll almost always have fields that shouldn't be serialized. Maybe it's a password, a temporary session token, or a reference to a massive database connection object that wouldn't make sense to save to a file. You handle this with the transient keyword.

If you mark a field as transient, Java simply skips it during the serialization process. When you deserialize the object later, that field will be initialized to its default value (null for objects, 0 for ints, etc.).

public class PlayerProfile implements Serializable {
    public String username;
    public int level;
    
    // We don't want to save the temporary session ID to the disk
    public transient String currentSessionToken; 

    public PlayerProfile(String username, int level, String token) {
        this.username = username;
        this.level = level;
        this.currentSessionToken = token;
    }
}

Why do I keep seeing "serialVersionUID" mentioned everywhere?

This is where things can get messy. When Java serializes an object, it attaches a version number to the byte stream. If you don't provide one, Java calculates one automatically based on the class's fields and methods.

Here is the problem: if you save a PlayerProfile to a file, then you go back into your code and add a new field (like int goldCoins), the automatically generated ID changes. When you try to load that old save file, Java will notice the IDs don't match and throw an InvalidClassException. It basically says, "The class you're using now isn't the same as the class that created this file."

To prevent this, I always explicitly define a serialVersionUID. This tells Java, "Trust me, these classes are compatible," allowing you to evolve your class without breaking old saved data.

public class PlayerProfile implements Serializable {
    private static final long serialVersionUID = 1L; // Manually locking the version
    public String username;
    public int level;
}



📋 Practical Task

Build a Persistent Game Settings Manager

Your task is to create a system that saves and loads user preferences for a game. This will test your ability to handle serialization, ignore sensitive/temporary data, and ensure version compatibility.

  • Create a class GameSettings that implements Serializable.
  • Add a serialVersionUID of 42L.
  • Give it the following fields: String playerName, int volumeLevel, boolean fullscreenMode, and a transient String lastLoginIp.
  • Write a SettingsManager class with two methods:
    • saveSettings(GameSettings settings, String filename): Uses ObjectOutputStream to write the settings to a file.
    • loadSettings(String filename): Uses ObjectInputStream to read the settings back from the file and return the GameSettings object.
  • In your main method, create a GameSettings object with some values, save it to "config.dat", then create a new variable and load the settings from that file into it. Print the loaded values to the console to verify they match (and verify that lastLoginIp is indeed null).
Rating
0 0

There are no comments for now.

to be the first to leave a comment.