Serialisierung von Objekten in Java: Vollständiger Leitfaden mit Beispielen

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Serialisierung von Objekten in Java: Von den Grundlagen zu fortgeschrittenen Techniken

\n\n

Serialisierung ist der Prozess der Umwandlung des Zustands eines Objekts in einen Bytestrom, um ihn zu speichern (in einer Datei, Datenbank) oder über ein Netzwerk zu übertragen. Der umgekehrte Prozess – die Deserialisierung – stellt das Objekt aus dem Bytestrom wieder her. In Java ist dieser Mechanismus in die Plattform integriert und wird häufig in verteilten Systemen, Caching und Webanwendungen verwendet. In diesem Artikel werden wir untersuchen, wie die Serialisierung funktioniert, welche Schnittstellen und Klassen beteiligt sind und wie man eine benutzerdefinierte Serialisierung korrekt implementiert.

\n\n

Grundlagen: Das Serializable-Interface

\n\n

Damit ein Objekt serialisiert werden kann, muss seine Klasse das Marker-Interface java.io.Serializable implementieren. Dieses Interface enthält keine Methoden – es teilt der virtuellen Maschine lediglich mit, dass das Objekt serialisiert werden darf.

\n\n
import java.io.Serializable;\n\npublic class User implements Serializable {\n    private static final long serialVersionUID = 1L;\n    private String name;\n    private int age;\n\n    public User(String name, int age) {\n        this.name = name;\n        this.age = age;\n    }\n\n    @Override\n    public String toString() {\n        return "User{name='" + name + "', age=" + age + "}";\n    }\n}
\n\n

Das Feld serialVersionUID ist eine eindeutige Versionskennung der Klasse. Wenn es nicht explizit deklariert wird, berechnet die JVM es automatisch, was jedoch bei einer Änderung der Klasse zu einer InvalidClassException während der Deserialisierung führen kann. Es wird empfohlen, es immer manuell festzulegen.

\n\n

Der Serialisierungs- und Deserialisierungsprozess

\n\n

Zum Schreiben eines Objekts in einen Stream wird ObjectOutputStream verwendet, zum Lesen ObjectInputStream. Betrachten wir ein einfaches Beispiel:

\n\n
import java.io.*;\n\npublic class SerializationDemo {\n    public static void main(String[] args) {\n        User user = new User("Alexej", 30);\n\n        // Serialisierung\n        try (FileOutputStream fos = new FileOutputStream("user.ser");\n             ObjectOutputStream oos = new ObjectOutputStream(fos)) {\n            oos.writeObject(user);\n            System.out.println("Objekt serialisiert: " + user);\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n\n        // Deserialisierung\n        try (FileInputStream fis = new FileInputStream("user.ser");\n             ObjectInputStream ois = new ObjectInputStream(fis)) {\n            User restoredUser = (User) ois.readObject();\n            System.out.println("Objekt wiederhergestellt: " + restoredUser);\n        } catch (IOException | ClassNotFoundException e) {\n            e.printStackTrace();\n        }\n    }\n}
\n\n

Bei der Deserialisierung wird der Konstruktor des Objekts nicht aufgerufen – der Zustand wird direkt aus dem Stream wiederhergestellt. Dies ist ein wichtiger Unterschied zur normalen Objekterstellung mit new.

\n\n

Das Schlüsselwort transient

\n\n

Manchmal ist es notwendig, bestimmte Felder von der Serialisierung auszuschließen, z. B. Passwörter oder temporäre Berechnungen. Dafür wird der Modifikator transient verwendet. Felder, die damit markiert sind, erhalten bei der Serialisierung Standardwerte (0, null, false).

\n\n
public class UserWithPassword implements Serializable {\n    private static final long serialVersionUID = 1L;\n    private String login;\n    private transient String password; // wird nicht serialisiert\n\n    public UserWithPassword(String login, String password) {\n        this.login = login;\n        this.password = password;\n    }\n\n    @Override\n    public String toString() {\n        return "User{login='" + login + "', password='" + password + "'}";\n    }\n}
\n\n

Nach der Deserialisierung ist das Feld password null. Dies ist praktisch für die Sicherheit, erfordert aber eine zusätzliche Wiederherstellungslogik.

\n\n

Benutzerdefinierte Serialisierung: Methoden writeObject und readObject

\n\n

Wenn das Standardverhalten nicht ausreicht, können die privaten Methoden

Empfehlungen