Java
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Object-Oriented Java
-
Section 4: Collections Framework
-
Section 5: Exception Handling
-
Section 6: Generics
-
Section 7: Functional Java
-
Section 8: Concurrency
-
Section 9: I/O and NIO
-
Section 10: JVM Internals
-
Section 11: Modern Java Features
-
Section 12: Build Tools and Project Structure
-
Section 13: Testing
-
Section 14: Databases and Persistence
-
Section 15: Networking
-
Section 16: Design and Best Practices
-
Section 17: Reflection and Annotations
-
Section 18: Logging and Diagnostics
-
Section 19: Date, Time, and Internationalization
-
Section 20: Java Platform Module System
-
Section 21: Security in Java
-
Section 22: Advanced Collections and Data Structures
-
Section 23: More Concurrency Patterns
-
Section 24: Compression, Files, and System Integration
-
Section 25: GUI Programming
-
Section 26: Practical Projects
-
Section 27: Data Structures and Algorithms
-
Section 28: Interview and Algorithm Practice
-
Section 29: JSON and Data Interchange
-
Section 30: More Concurrency Utilities
-
Section 31: More Collections and Streams Practice
-
Section 32: More File and System Programming
-
Section 33: Standard Library Deep Dive
-
Section 34: More Practice and Drills
-
Section 35: More Testing and Quality
-
Section 36: More Design Patterns and Architecture
-
Section 37: Career and Ecosystem
-
Section 38: More OOP and Architecture Practice
-
Section 39: More Enterprise Concepts
-
Section 40: Advanced JavaFX
-
Section 41: More Interview Practice
97: Serialization Basics
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
GameSettingsthat implementsSerializable. - Add a
serialVersionUIDof42L. - Give it the following fields:
String playerName,int volumeLevel,boolean fullscreenMode, and atransient String lastLoginIp. - Write a
SettingsManagerclass with two methods:saveSettings(GameSettings settings, String filename): UsesObjectOutputStreamto write the settings to a file.loadSettings(String filename): UsesObjectInputStreamto read the settings back from the file and return theGameSettingsobject.
- In your
mainmethod, create aGameSettingsobject 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 thatlastLoginIpis indeednull).
There are no comments for now.