Daniel Thoma: Sessions und Serialisierbarkeit

Beitrag lesen

Hallo Biesterfeld,

Kann ich das in irgendeinerweise umgehen?

Damit kenne ich mich nicht aus. Es könnte sein, dass das implementierungsabhängig ist. Vernünftige Datenobjekte sollten aber sehr leicht serialisierbar sein.

Um ein Objekt serialisierbar zu machen, genügt es schon, Serializable zu implementieren und keine Eigenschaften als final zu deklarieren.
Zusätzlich ist es noch sinnvoll die Konstante serialVersionUID zu deklarieren um eine Version der Klasse anzugeben und nicht zu speichernde Eigenschaften als transient zu deklarieren.
Eine Implementierung von readObject und wirteObject ist nicht notwendig, so lange das Standardverfahren ausreicht. Wenn Du das irgendwie erweitern willst um z.B. irgend welche als transient markierten Attribute beim deserialisieren neu zu berechnen, musst Du darauf achten, dass Du dann die Standardverfahren explizit aufrufen musst.

Die Objekte nach XML zu serialisieren ist keine gute Idee. Ein ObjectStream erlaubt es, direkt Objekte, Arrays usw. auszugeben. Dadurch wird der Implementierung erlaubt, diese Datenstrukturen in einem optimierten Format zu speichern. Wenn Du erst mal XML daraus machst, ist diese Möglichkeit weg.
Wenn Du keinen sehr guten Grund hast, solltest Du die Methoden nicht implementieren

Ebensowenig, wie dass readObject() nicht statisch ist und keinen Rückgabewert hat.

Wenn Du direkt mit ObjectStreams arbeiten würdest, würde das so ablaufen:

Du erstellst einen ObjectOutputStream und schreibst ein Objekt mit writeObject(Object). Java wird dann irgendwelche Metadaten des Objekts über den ObjectOutputStream ausgeben und für alle referenzierten Objekte rekursiv  wieder writeObject(Object) aufrufen. Irgendwie werden dabei auch Zyklen abgefangen.
Falls writeObject(Stream) implementiert ist, wird Java die Serialisierung der Eigenschaften nicht automatisch durchführen, sondern nur wirteObject aufrufen. Das kann dann einige Daten in den ObjectStream ausgeben.

Wenn nun deserialisiert wird, würdest Du einen ObjectInputStream erstellen und mit Object readObject() das erste Objekt lesen. Java würde dieses Objekt mit hilfe der Daten, die es vom Stream liest, erzeugen und wiederum für alle referenzierten Objekte diese mit readObject einlesen.
Wenn readObject(Stream) implementiert ist, wird das aufgerufen und muss nun genau die Daten einlesen, die readObject vorher ausgegeben hat.
readObject(Stream) erzeugt also nicht das Objekt sondern stellt nur Werte seiner Eigenschaften wieder her.

Wichtig ist, dass die Objektstruktur genau in der gleichen Reihenfolge wie beim Serialisieren abgearbeitet wird. Wenn man readObject und writeObject implementiert, muss man darauf natürlich auchten.

Statt zu beschreiben, wie man ein Objekt serialisiert, kann es einfacher sein, einfach ein einfaches anderes Objekt zu erzeugen, und dieses stattdessen zu serialisieren. (Siehe writeReplace und readResolve)
Das ist außerdem notwendig, wenn man die Serialisierung lange speichern will und alte Serialisierungen nach Änderung der internen Objektstruktur wieder lesen können muss.

Grüße

Daniel