11_Serializable

Code-Dateien

DateinameAktion
CODECode_Fahrzeug.zipDownload
CODECode_Mitarbeiter_D.zipDownload

Videos

DateinameAktion
VIDEOVideo_Fahrzeug_DAbspielen
VIDEOVideo_Mitarbeiter_DAbspielen

Lernmaterialien

Serialisierten Dateien

In Java meint man mit serialisierten Dateien meist Dateien, in die man Objekte so speichert, dass man sie später wieder als Java-Objekte einlesen kann. Das passiert über Serialization: Ein Objekt wird in eine Bytefolge umgewandelt und in eine Datei geschrieben; beim Lesen wird es wieder zu einem Objekt (Deserialization).

Wozu?

  • Objekte persistent speichern (z. B. Spielstand, Konfiguration, Cache)

  • Objekte übertragen (z. B. über Netzwerk; historisch häufig genutzt)

Änderung der Basisklasse

Wenn sich die Klasse eines serialisierten Objekts ändert, kann das Einlesen (Deserialisieren) je nach Art der Änderung weiter funktionieren – oder mit Fehler abbrechen. Entscheidend ist vor allem die serialVersionUID.

Wie funktioniert das?

  • Die Klasse muss implements Serializable haben.

  • Schreiben/Lesen meist über ObjectOutputStream / ObjectInputStream.

Student.java

public abstract class Student implements Serializable {
    private static final long serialVersionUID = 1L;

School.java

    public void saveSchool(String filename) throws StudentException {
        FileOutputStream fos;
        ObjectOutputStream oos;

        try {
            fos = new FileOutputStream(filename);
            oos = new ObjectOutputStream(fos);
            oos.writeObject(students);
            oos.close();
            fos.close();
        }
        catch (FileNotFoundException e) {
            throw new StudentException("Datei oder Pfad nicht vorhanden!");
        }
        catch (IOException e) {
            throw new StudentException("Kann die Datei nicht beschreiben!");
        }
    }

School.java

    public void loadSchool(String filename) throws StudentException {
        FileInputStream fis;
        ObjectInputStream ois;

        try {
            fis = new FileInputStream(filename);
            ois = new ObjectInputStream(fis);
            students = (ArrayList<Student>) ois.readObject();
            ois.close();
            fis.close();
        }
        catch (FileNotFoundException e) {
            throw new StudentException("Datei oder Pfad nicht vorhanden!");
        }
        catch (IOException e) {
            throw new StudentException("Kann die Datei nicht lesen!");
        }
        catch (ClassNotFoundException e) {
            throw new StudentException("Keine gültige Daten!");
        }
    }

SchoolTest.java

    @Test
    public void testSaveLoadSchool() {
        School s, x;
        s = new School();
        x = new School();

        try {
            s.importSchool("daten.txt");
            System.out.println(s);
            assertEquals(5, s.anzahlStudent());
            s.saveSchool("daten.ser");
            x.loadSchool("daten.ser");
            System.out.println("====");
            System.out.println(x);
            assertEquals(5, x.anzahlStudent());
            assertEquals(s.toString(), x.toString());
        }
        catch (StudentException e) {
            System.out.println(e.getMessage());
        }
    }

Wichtige Punkte / Stolpersteine

  • serialVersionUID: Versionskennung. Hilft, wenn sich die Klasse ändert (sonst kann InvalidClassException auftreten).

  • transient: Felder, die nicht serialisiert werden sollen.

  • Nicht für Sicherheit geeignet: Deserialisierung von untrusted Daten ist riskant (bekannte Angriffsklasse). Für externe Daten eher JSON/XML/TXT verwenden.