1. Binäre Serialisierung in Java
Binäre Serialisierung ist ein Standardmechanismus in Java, bei dem ein Objekt möglichst kompakt und schnell in einen Bytestrom verwandelt wird. Dafür werden die Klassen ObjectOutputStream und ObjectInputStream verwendet. Die resultierende Datei ist ein Satz von Bytes, der nicht für das menschliche Lesen gedacht ist.
Sie heißt binär, weil alles im „rohen“ Zustand serialisiert wird: Zahlen, Strings, Arrays, sogar Verweise zwischen Objekten werden zu Bytes. Das ist wie ein dicht gepackter Koffer: effizient und schnell, aber ohne Anleitung ist nicht offensichtlich, wo was liegt.
Wie funktioniert das in Java?
Nehmen wir an, wir haben eine Klasse User:
import java.io.Serializable;
public class User implements Serializable {
private String name;
private int age;
// Konstruktor, Getter und Setter
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() { return name; }
public int getAge() { return age; }
}
Serialisierung in eine Binärdatei
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
User user = new User("Vasya", 30);
try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("user.bin"))) {
out.writeObject(user);
System.out.println("User-Objekt wurde in die Datei user.bin serialisiert");
} catch (Exception e) {
e.printStackTrace();
}
Deserialisierung aus einer Binärdatei
import java.io.FileInputStream;
import java.io.ObjectInputStream;
try (ObjectInputStream in = new ObjectInputStream(new FileInputStream("user.bin"))) {
User loadedUser = (User) in.readObject();
System.out.println("Aus Datei gelesen: " + loadedUser.getName() + ", " + loadedUser.getAge());
} catch (Exception e) {
e.printStackTrace();
}
Achtung: Wenn Sie die Datei user.bin in einem Texteditor öffnen, sehen Sie etwas wie: ¬í sr ... – das ist normal und so vorgesehen!
Vorteile der binären Serialisierung
- Kompaktheit und Geschwindigkeit. Speichern und Lesen erfolgen so schnell wie möglich, ohne zusätzliche „Verzierungen“.
- Alle Felder des Objekts werden gespeichert, einschließlich verschachtelter Objekte (sofern diese ebenfalls über Serializable serialisierbar sind).
- Einfach zu verwenden für internen Cache oder die Übertragung zwischen Java-Programmen.
Nachteile
- Schwer lesbar. Ein Mensch kann nicht „hineinspicken“ und verstehen, was drinsteht.
- Starre Bindung an die Klassenversion. Eine Strukturänderung (Felder hinzufügen/entfernen) kann das Lesen alter Dateien „brechen“.
- Kompatibilitätsprobleme zwischen verschiedenen Versionen von Java und der JVM.
- Nicht geeignet für den Austausch mit anderen Programmiersprachen.
- Sicherheit: Die Deserialisierung von Daten aus nicht vertrauenswürdigen Quellen ist ein direkter Weg zu Schwachstellen.
2. Textbasierte Serialisierungsformate: JSON, XML und andere
Binäre Serialisierung ist gut für die interne Nutzung, aber oft müssen Daten zwischen verschiedenen Sprachen (Java, JavaScript, Python) ausgetauscht oder in lesbarer Form gespeichert werden – praktisch für Konfigurationen, Logs, APIs. Dafür werden textbasierte Formate genutzt: JSON, XML, YAML, CSV u. a.
JSON – am weitesten verbreitet
JSON (JavaScript Object Notation) ist ein kompaktes und gut lesbares Format. Beispiel für ein serialisiertes User-Objekt:
{
"name": "Vasya",
"age": 30
}
In Java werden für die Arbeit mit JSON meist Bibliotheken verwendet: Jackson (am populärsten), Gson sowie Moshi, JSON-B u. a.
XML – ein alter Bekannter für Programmierende
XML (Extensible Markup Language) ist „wortreicher“, aber formal und streng.
<User>
<name>Vasya</name>
<age>30</age>
</User>
Für XML wird in Java häufig die Standardbibliothek JAXB eingesetzt (oder die ältere XStream).
YAML, CSV und andere
- YAML ähnelt JSON, ist aber knapper; wird häufiger für Konfigurationen genutzt als für die Serialisierung komplexer Objekte.
- CSV ist gut für „flache“ Tabellen, eignet sich jedoch schlecht für verschachtelte Strukturen.
- Es gibt Formate für jeden Geschmack, in Java werden jedoch am häufigsten JSON und XML verwendet.
3. Vergleich der Formate: wann welches verwenden?
| Format | Lesbarkeit | Kompaktheit | Geschwindigkeit | Kompatibilität | Wann verwenden |
|---|---|---|---|---|---|
| Binär | Nein | ++ | ++ | Nur Java | Interner Cache, schnelle Speicherung zwischen JVMs |
| JSON | Ja | + | + | Beliebige Sprachen | REST-APIs, Austausch mit externen Diensten, Konfigurationen |
| XML | Ja | - | - | Beliebige Sprachen | Integration, strenge Schemata, Altsysteme |
- Binär – wählen Sie es für die interne Nutzung, wenn kein Austausch mit externen Systemen erforderlich ist und maximale Performance wichtig ist.
- JSON – die beste Wahl für den Austausch mit Webanwendungen, mobilen Clients und REST-APIs sowie zur Speicherung von Einstellungen.
- XML – erforderlich bei strengen Schemata und Integration mit „Enterprise“-Lösungen.
Wichtig! Binäre Serialisierung eignet sich nur für die Übertragung von Daten zwischen Java-Programmen, und selbst dann ist es sicherer, sie zwischen Programmen derselben Version zu verwenden. Textformate wie JSON und XML sind universeller: Sie eignen sich für den Datenaustausch zwischen verschiedenen Sprachen und Plattformen und machen Informationen lesbar und portabel.
4. Praxis: Serialisierung in Binär- und Textformat
Binäre Serialisierung (ObjectOutputStream/ObjectInputStream)
Schon oben gesehen, aber zur Festigung noch einmal:
// Serialisierung
try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("user.bin"))) {
out.writeObject(user);
}
// Deserialisierung
try (ObjectInputStream in = new ObjectInputStream(new FileInputStream("user.bin"))) {
User loadedUser = (User) in.readObject();
}
Serialisierung in JSON mit Jackson (kurz)
Um mit Jackson zu arbeiten, müssen die Bibliotheken dem Projekt hinzugefügt werden. Wir behandeln später Maven und Gradle, vorerst können die JAR-Dateien manuell eingebunden werden. Beispiel für eine Maven-Abhängigkeit:
<!-- Maven -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.17.0</version>
</dependency>
Beispiel für Serialisierung/Deserialisierung:
import com.fasterxml.jackson.databind.ObjectMapper;
User user = new User("Vasya", 30);
ObjectMapper mapper = new ObjectMapper();
try {
// Serialisierung in einen String
String json = mapper.writeValueAsString(user);
System.out.println(json); // {"name":"Vasya","age":30}
// Serialisierung in eine Datei
mapper.writeValue(new File("user.json"), user);
// Deserialisierung aus einem String
User loadedUser = mapper.readValue(json, User.class);
// Deserialisierung aus einer Datei
User loadedFromFile = mapper.readValue(new File("user.json"), User.class);
} catch (Exception e) {
e.printStackTrace();
}
Eine JSON-Datei kann in jedem Texteditor geöffnet werden, was die Daten leicht lesbar und zwischen verschiedenen Anwendungen und Sprachen übertragbar macht.
5. Welches Format wann verwenden: Praxistipps
- Internes Caching, temporäre Dateien, schnelle Schreib-/Lesevorgänge zwischen Java-Programmen: Verwenden Sie die Standard-binäre Serialisierung. Denken Sie jedoch an die Versionskompatibilität!
- Austausch mit externen Diensten, Speichern von Einstellungen, Integration mit dem Frontend: Verwenden Sie JSON (Jackson, Gson).
- Integration mit „Enterprise“-Systemen, bei denen ein strenges Schema erforderlich ist: XML (JAXB).
- Die Datei soll von Menschen geöffnet und gelesen werden können: JSON oder XML, aber kein binäres Format.
6. Typische Fehler im Umgang mit Serialisierungsformaten
Fehler Nr. 1: Es wird versucht, ein Objekt mit nicht serialisierbaren Feldern zu serialisieren. Wenn Ihre Klasse ein Feld hat, das Serializable nicht implementiert (z. B. einen Stream oder eine DB-Verbindung), führt die binäre Serialisierung zu einem Fehler. Für JSON ist das weniger kritisch, aber auch bei „nicht standardmäßigen“ Typen kann es Probleme geben.
Fehler Nr. 2: Eine Binärdatei wird in einem Texteditor geöffnet und sorgt für Verwirrung. Das ist normal! Binärdateien sind nicht für das menschliche Lesen bestimmt.
Fehler Nr. 3: Die Klassenstruktur wird geändert und alte Binärdateien lassen sich nicht mehr lesen. Binäre Serialisierung ist empfindlich gegenüber Strukturänderungen der Klasse – häufig tritt eine InvalidClassException auf. In JSON/XML ist das weniger kritisch: Unbekannte Felder werden üblicherweise ignoriert oder erhalten Standardwerte.
Fehler Nr. 4: Binäre Serialisierung wird für den Austausch mit externen Systemen verwendet. Das funktioniert nicht: Das binäre Format versteht nur Java – und auch dann nur bei übereinstimmenden Versionen.
Fehler Nr. 5: Für JSON/XML werden erforderliche Annotationen vergessen. Manche Bibliotheken benötigen Annotationen wie @JsonProperty, @XmlElement, andernfalls kann die Serialisierung/Deserialisierung nicht wie erwartet funktionieren.
Fehler Nr. 6: Es wird nicht geprüft, ob alle verschachtelten Objekte serialisierbar sind. Für die binäre Serialisierung ist das ein häufiger Stolperstein; für JSON ebenso, wenn im Modell komplexe Typen vorkommen.
GO TO FULL VERSION