0Pricing
Java Academy · Lektion

Benutzerdefinierte Serialisierung: writeObject und readObject

Überschreiben Sie writeObject und readObject für Verschlüsselung, Komprimierung oder die individuelle Verarbeitung von Feldern.

Benutzerdefinierte Serialisierung: writeObject und readObject ist eine kostenlose Java Academy-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Java Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Java Academy-Kurs umfasst insgesamt 4 Lektionen.

Wenn die Standardsserialisierung nicht ausreicht

Die Standardsserialisierung speichert alle nicht-transienten Felder unverändert. Manchmal benötigen Sie Verschlüsselung, Komprimierung oder eine andere Darstellung. Dafür gibt es die Hooks writeObject und readObject.

writeObject deklarieren

Fügen Sie eine Methode private void writeObject(ObjectOutputStream oos) hinzu. Java ruft sie anstelle des Standardmechanismus auf. Sie steuern genau, was geschrieben wird.

private void writeObject(ObjectOutputStream oos) throws IOException {
    oos.defaultWriteObject(); // write non-transient fields normally
    oos.writeUTF(encrypt(this.secret)); // write encrypted secret
}

readObject deklarieren

Fügen Sie eine Methode private void readObject(ObjectInputStream ois) hinzu. Java ruft sie während der Deserialisierung auf. Lesen Sie die Daten in exakt derselben Reihenfolge ein, in der Sie sie geschrieben haben.

private void readObject(ObjectInputStream ois)
        throws IOException, ClassNotFoundException {
    ois.defaultReadObject(); // restore non-transient fields
    this.secret = decrypt(ois.readUTF()); // decrypt and restore
}

Die Reihenfolge ist entscheidend

Alles, was Sie in writeObject schreiben, muss in readObject in derselben Reihenfolge wieder eingelesen werden. Eine abweichende Reihenfolge führt zu einer StreamCorruptedException.

private void writeObject(ObjectOutputStream oos) throws IOException {
    oos.writeInt(version);
    oos.writeUTF(data);
}
private void readObject(ObjectInputStream ois)
        throws IOException, ClassNotFoundException {
    this.version = ois.readInt();  // same order
    this.data    = ois.readUTF();
}

Daten während der Serialisierung komprimieren

Umschließen Sie den Stream in writeObject mit GZIPOutputStream, um große Felder zu komprimieren, und verwenden Sie in readObject anschließend GZIPInputStream zum Dekomprimieren.

private void writeObject(ObjectOutputStream oos) throws IOException {
    oos.defaultWriteObject();
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    try (GZIPOutputStream gz = new GZIPOutputStream(bos)) {
        gz.write(largePayload.getBytes());
    }
    oos.writeObject(bos.toByteArray());
}

Der readResolve-Hook

readResolve() wird nach der Deserialisierung aufgerufen. Geben Sie ein Ersatzobjekt zurück – nützlich für Singletons und Enums, damit nach der Deserialisierung nur eine Instanz existiert.

public class AppConfig implements Serializable {
    private static final AppConfig INSTANCE = new AppConfig();
    private AppConfig() {}
    public static AppConfig getInstance() { return INSTANCE; }
    private Object readResolve() { return INSTANCE; } // return singleton
}

Der writeReplace-Hook

writeReplace() wird vor der Serialisierung aufgerufen. Geben Sie ein anderes Objekt zurück, das stattdessen serialisiert werden soll – nützlich für Proxy-Muster und Serialisierungsersatzobjekte.

private Object writeReplace() {
    return new UserProxy(this.id); // serialize a lightweight proxy
}

Felder in readObject validieren

Sie können innerhalb von readObject Validierungslogik hinzufügen, um ungültige oder manipulierte Daten im Rahmen einer mehrschichtigen Sicherheitsstrategie abzulehnen.

private void readObject(ObjectInputStream ois)
        throws IOException, ClassNotFoundException {
    ois.defaultReadObject();
    if (age < 0 || age > 150) {
        throw new InvalidObjectException("Invalid age: " + age);
    }
}

Versionsänderungen behandeln

Verwenden Sie in writeObject ein Versionsfeld, damit readObject während Migrationen alte und neue Formate problemlos verarbeiten kann.

private static final int SERIAL_VERSION = 2;
private void writeObject(ObjectOutputStream oos) throws IOException {
    oos.defaultWriteObject();
    oos.writeInt(SERIAL_VERSION);
    if (SERIAL_VERSION >= 2) oos.writeUTF(email); // new field
}
private void readObject(ObjectInputStream ois)
        throws IOException, ClassNotFoundException {
    ois.defaultReadObject();
    int v = ois.readInt();
    if (v >= 2) this.email = ois.readUTF();
}

Serialisierungs-Proxy-Muster

Ein robustes Vorgehen: Schreiben Sie eine private statische innere Klasse, die den minimal erforderlichen Zustand erfasst, und verwenden Sie dann writeReplace, um den Proxy zu schreiben, sowie dessen readResolve, um das ursprüngliche Objekt wiederherzustellen.

Überlegungen zur Leistung

Benutzerdefinierte Serialisierung verursacht zusätzlichen Aufwand durch Methodenaufrufe, kann die Größe der Nutzdaten aber erheblich reduzieren. Führen Sie vor der Optimierung Benchmarks durch; verwenden Sie Externalizable für maximale Kontrolle.

Kurze Überprüfung

Was muss für die Reihenfolge in writeObject und readObject gelten?

Zusammenfassung

Überschreiben Sie writeObject und readObject für Verschlüsselung, Komprimierung oder benutzerdefinierte Formate. Verwenden Sie readResolve für Singletons. Lesen Sie immer in derselben Reihenfolge, in der Sie schreiben.

Häufig gestellte Fragen

Ist die Lektion „Benutzerdefinierte Serialisierung: writeObject und readObject“ kostenlos?

Ja — der vollständige Text von „Benutzerdefinierte Serialisierung: writeObject und readObject“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Java Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Java Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Benutzerdefinierte Serialisierung: writeObject und readObject“?

Überschreiben Sie writeObject und readObject für Verschlüsselung, Komprimierung oder die individuelle Verarbeitung von Feldern. Du übst Java Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Java Academy zu starten?

Keine Vorkenntnisse erforderlich. Java Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.

Wie lange dauert die Lektion „Benutzerdefinierte Serialisierung: writeObject und readObject“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Java Academy-Lektion Code schreiben und ausführen?

Ja. Jede Java Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Grundlagen der Java-Serialisierung
  2. transient-Felder und serialVersionUID
  3. Benutzerdefinierte Serialisierung: writeObject und readObject
  4. Moderne Alternativen: JSON und Protocol Buffers
← Zurück zu Java Academy