11.1.1 Beispiele Schnittstellenanwendung
11.1.1 Beispiele SchnittstellenanwendungSerialisierung
Serialisierung ist ein Beispiel bei dem man gut sieht wie eine Klasse durch Implementierung einer Schnittstelle wichtige Eigenschaften gewinnen man. Man kann sie in einer Datei speichern oder in einen beliebigen Stream stecken!
Java bietet die Möglichkeit Objekte im Hauptspeicher in einen seriellen Datenstron zu konvertieren den man zum Beispiel in Dateien schreiben kann. Diese Technologie nennt man Serialisierung(engl. Serialization siehe Wikipedia). Java kann Klassen serialisieren die die Schnittstelle Serializable implementieren.
Java kann Objekte serialisieren wenn
- die entsprechende Klasse die Schnittstelle Serializable implementiert und
- wenn alle Attribute die auf Objekte zeigen auch die Schnittstelle Serializable implementieren
Das folgende Beispielprogramm ist in der Lage eine Person und ihre Adresse in eine Datei zu schreiben und wieder zu lesen.
Alles was man tun muss um die Klassen Person und Adresse serialisierbar zu machen ist die Schlüsselworte "implements Serializable" hinzuzufügen
|
Überlegungen:
- Die Schnittstelle Serializable fordert keine Methoden zu implementieren!
- Warum sind 4 Objekte in der Datei?
- Was würde geschehen wenn die die Klasse Person mit Stammbaum aus der ersten Vorlesung serialisieren würde?
- Was würde geschehen wenn man weitere Attribute mit Basistypen zu den Klassen hinzufügt?
- Was geschieht wenn man auf eine Klasse referenziert die nicht serialisierbar ist?
Klasse Serialisierung
package s1.block11; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; /** * * @author s@scalingbits.com */ public class Serialisierung { /** * Erzeuge eine Person und die Adresse. Schreibe sie in eine * Datei und lese sie aus der Datei * @param args */ public static void main(String[] args) { final String meineDatei = "serialisiert.ser"; // Erzeuge das Objekt der Person und das Objekt mit der Adresse Person p = new Person("Urmel", new Adresse("Lummerland")); System.out.println("Zu schreibende Person " + p.name + " wohnt in " + p.wohnort.stadt); // Schreibe die Objekte in eine Datei schreiben(p, meineDatei); Person p1 = (Person) lesen(meineDatei); System.out.println("Gelesene Person " + p1.name + " wohnt in " + p1.wohnort.stadt); System.out.println("Die geschrieben Adresse und die gelesene"+ " Adresse " + p.wohnort.stadt + " sind" + (p.wohnort==p1.wohnort? " " : " nicht ") + "identisch"); } /** * Diese Methode schreibt ein beliebiges serialisierbares Objekt * in eine Datei * @param o Objekt welches in eine Datei geschrieben wird. * Es muss serialisierbar sein! * @param datei Die Datei in die geschrieben werden soll */ public static void schreiben(Object o, String datei) { try { // Erzeuge einen Stream der in eine Datei geleitet wird FileOutputStream fileOut = new FileOutputStream(datei); // Erzeuge einen Stream der Objekte in einen Filestream leitet ObjectOutputStream out = new ObjectOutputStream(fileOut); // Schreibe ein beliebiges Objekt in diesen Objectstream out.writeObject(o); // Schliesse Stream out.close(); // Schliesse Datenstrom. Die letzten Bytes werden so raus geschrieben fileOut.close(); System.out.println("Serialisierte Daten sind gespeichert in Datei " + datei); } catch (IOException i) { // Hier können Ausnahmen auftreten i.printStackTrace(); } } /** * * @param datei die Datei aus der gelesen werden soll * @return */ public static Object lesen(String datei) { System.out.println("Lesen aus " + datei); Object o; try { // Hier können Ausnahmen Auftreten // Öffne Datei aus der gelesen werden soll FileInputStream fileIn = new FileInputStream(datei); // Erzeuge Objectstream der aus Datei liest ObjectInputStream in = new ObjectInputStream(fileIn); //Lies Objekt aus Stream o = in.readObject(); // Schließe Objectstream in.close(); // Schließe Datei fileIn.close(); } catch (IOException i) { // Wird ausgeführt wenn Probleme auftreten i.printStackTrace(); return null; } catch (ClassNotFoundException c) { System.out.println("Gelesene Klasse nicht gefunden"); c.printStackTrace(); return null; } return o; } }
Klasse Adresse
package s1.block11; import java.io.Serializable; /** * * @author s@scalingbits.com */ public class Adresse implements Serializable { String stadt; public Adresse (String s) { stadt =s; } }
Klasse Person
package s1.block11; import java.io.Serializable; /** * * @author s@scalingbits.com */ public class Person implements Serializable { String name; Adresse wohnort; public Person(String n, Adresse w) { wohnort = w; name=n; } }
Weiterführende Übungen und Überlegungen zu diesem Beispiel
- Was geschieht wenn zwei Personen auf das gleiche Adressobjekt zeigen? Wird die Adresse zweimal gespeichert oder nur einmal? Selbst wenn die Adresse nur einmal gespeichert wird. Was geschieht beim Lesen der serialisierten Datei. Wird das Addressobjekt verdoppelt?
- Was geschieht beim Übersetzen und Ausführen wenn man den Term "implements Serializable" in der Klasse Adresse oder Person weglässt?
- Versioning Problem: Was geschieht wenn man die Objekte in eine Datei serialisiert. Dann ein Attribut zu einer Klasse hinzufügt oder weglässt. Dann die serialisierten Objekt wieder einliest?
- Was muss man tun wenn man ein Attribut (zBsp. stadt) nicht speichern möchte? Suchen Sie in der Java-Spezifikation oder mit einer Suchmaschine...
- 4644 views