# Serial Version ID?



## nrg (15. Dez 2009)

Hallo Zusammen,

ich hab mich jetzt schon öfters gefragt, was die Entwicklungsumgebung Eclipse mir damit sagen will:







Was ist die Serial Version ID und warum soll man die als konstantes Attribut reinnehmen?

Danke und Grüße
andi


----------



## The_S (15. Dez 2009)

Hat was mit Objektserialisierung zu tun:

Java Blog Buch : 09.08 Objekte speichern und laden (serialisieren/deserialisieren) (unter "Versionskontrolle")


----------



## nrg (15. Dez 2009)

achso, weil die Klasse Vector das Interface Serializable implementiert, ich damit Objekte vom typ Telefonbuch speichern könnte und dazu dann eine Seriennummer für die Klasse bräuchte??


----------



## The_S (15. Dez 2009)

erste zwei Teile: ja, letzter Teil ("Seriennummer für die Klasse bräuchte") nein, du brauchst die Nummer nicht, sie ist nur zu empfehlen (steht auch in dem Artikel).


----------



## maki (15. Dez 2009)

Wobei sich die Geister scheiden ob es wirlich empfehlenswert immer ist eine SUID zu haben, denn dann geht man davon aus, zwischen verschiedenen Verisonen zu de-/serialisieren, und ich glaube das haben nur die wenigsten vor 
Für alle anderen ist die SUID gefährlich.


----------



## Spacerat (15. Dez 2009)

Also ich sag' mal: Wenn die IDE vor einer fehlenden SUID warnt, sollte man diese auch einfügen, denn wenn von der JVM keine gefunden wird, wird diese aufgrund des Bytecodes stets neu berechnet und afaik werden dazu auch Member herangezogen, die nicht serialisiert werden sollten (transient). Wenn die Klasse niemals zum Serialisieren gedacht ist, sollte man "1L" nehmen. Ansonsten lässt man eine SUID von der IDE berechnen und ändert diese in der Entwicklungsphase nicht mehr, solange sich am Serialisierungsvorgang nichts ändert (z.B. neuer Member soll serialisiert werden). Solange nur Methoden oder trantsistente Member der Klasse hinzugefügt oder geändert werden bleibt die einmal berechnete SUID gültig (im Gegensatz zur von der JVM stets neu berechneten). So können dann auch Objekte einer früheren Version in die neue Klasse deserialisiert werden. Diese Objekte sind also erst dann verloren, wenn sich der Serialisierungsvorgang geändert hat.
@maki: Dagegen, das es die wenigsten vorhaben, spricht, dass es sich meistens gar nicht vermeiden lässt.


----------



## The_S (18. Dez 2009)

Hm, also ich teile da eher die Meinung von maki. Wer serialisiert schon sein JFrame  . Und bevor nur das sinnlose 1L angegeben wird, bevorzuge ich die Annotation [c]@SuppressWarnings("serial")[/c]


----------



## Spacerat (18. Dez 2009)

Nun ja... Wenn ich ehrlich sein soll, hast du bei AWT-/Swing-Componenten irgendwie Recht. Es hätte genügt, wenn Applets nur serialisierbar gewesen wären. Aber was bitte ist am "1L" denn sinnlos? "SupressWarnings" zeugt nicht gerade von gutem Programmierstil und "1L" ist immerhin noch besser als von Kompilat zu Kompilat neu berechnet. Standard halt. Was solls... jedem das Seine.


----------



## w0ddes (18. Dez 2009)

Spacerat hat gesagt.:


> [...]
> Was solls... jedem das Seine.



Und auf dieses Statement hin: Keine weitere Diskussion! Jeder hat seine Art und da beide funktionieren ist doch alles okay


----------



## The_S (18. Dez 2009)

Spacerat hat gesagt.:


> Aber was bitte ist am "1L" denn sinnlos? "SupressWarnings" zeugt nicht gerade von gutem Programmierstil und "1L" ist immerhin noch besser als von Kompilat zu Kompilat neu berechnet. Standard halt. Was solls... jedem das Seine.



Sorry, sinnlos war wohl etwas hart ausgedrückt. Meinte eher sowas wie "ich greife lieber auf die Annotation zurück"  .


----------



## nrg (18. Dez 2009)

ok danke für die information . hab jetzt zumindest verstanden wie man damit umzugehen hat. leider noch nicht ganz warum und für was die jvm diese komische seriennummer beim speichern von objekten braucht aber damit muss ich mich wohl mal genauer befassen, wenn ich das vorhabe. bis dahin werd ich halt immer, wenn die entwicklungsumgebung meckert den std von "1L" einfügen .
grüße


----------



## tfa (18. Dez 2009)

Ich würde wie the_S auch eher zu SuppressWarnings raten. "1L" halte ich für schlechten Stil. Wenn man eine UID angibt, bedeutet das für mich, dass man die Klasse serialisieren will. Ein "1L" würde ich dann eher für eine Unachtsamkeit halten, als schlecht gewählten Defaultwert. Die SuppressWarnings-Annotation ist ja nur eine Art Kommentar. Sie zeigt, dass man verstanden hat, dass hier eine Serialisierung möglich wäre, man sich aber sicher ist, sie niemals durchzuführen. Vielleicht sollte man zusätzlich noch einen richtigen Kommentar dazu schreiben. Aber überall nur "1L" hinzuknallen ist Murks.


----------



## maki (18. Dez 2009)

> Wenn man eine UID angibt, bedeutet das für mich, dass man die Klasse serialisieren will.


Wenn man eine SUID angibt, bedeutet das: Man kann Objekte zwischen verschiedenen Klassenversionen de-/serialisieren und die Anwendung ist dafür ausgelegt... da ist ein großes Risiko mit verbunden 

Es ist ganz und gar kein guter Stil immer eine SUID zu haben, besonders wenn man eben nicht zwischen verschiedenen Versionen de-/serialisieren will, die Gefahr sollte selbsterklärend sein 

Leider hat Eclipse das in den Standardeinstellungen, und somit halten Leute es für eine gute Sache, obwohl sie es nicht ist.
Wenn ich keine SUID angebe, wird bei jedem kompilieren eine neue erzeugt, und ich merke garantiert falls ich verschiedene Versionen der Klassen habe 

Wenn man also nur Objekte zwischen gleichen Verisonen der Klasse de-/serialisieren will, sollte man auf jedenfall keine SUID vergeben und der Compiler & die Laufzeitumgebung stellen sicher dass das so bleibt, das ist der Standardfall.


----------



## tfa (18. Dez 2009)

maki hat gesagt.:


> Wenn man eine SUID angibt, bedeutet das: Man kann Objekte zwischen verschiedenen Klassenversionen de-/serialisieren und die Anwendung ist dafür ausgelegt...


Richtig, das sind darüber hinaus die technischen Auswirkungen, ich meinte eher die Intention des Entwicklers (d.h. wenn man die abgeleitete JComponent niemals in einen Object-Stream steckt, ist die Gefahr eines Versionskonflikts eher gering  )


----------



## fastjack (18. Dez 2009)

@maki Du sprichst mir aus dem Herzen.
@spacerat private static und private transient wird NICHT in die Berechnung der SerialVersionUID mit einbezogen.
@all Im Internet gibt es leider viele mißverständliche bzw. auch falsche Auslegungen der Berechnung und Verwendung dieses Identifikators. Man sollte lieber den Spezifikationen von SUN vertrauen.

Persönlich bevorzuge ich die automatische Berechnung, da bei allem was man selber einstellen muß, sich naturgemäß irgendwann die Routine(Faulheit) einschleicht und man das hochrechnen dieser Zahl einfach irgendwann vergißt. Das passiert bestimmt nicht bei zwei oder drei Klassen, bei 200 aber bestimmt.
Zudem bin ich bei RMI-Programmierung eigentlich selten böse überrascht worden, außer wenn ich an der Grundstruktur der Objekte etwas verändert hatte. Da die Serialisierung aber größtenteils zum Client-Server Datenaustausch genutzt werden sollte, ist bei einer Strukturveränderung ein Clientupdate eigentlich sinnvoll.
Wenn man aber seinen gesamten Datenbestand serialisiert auf Platte speichert, kann man sich bei einer Strukturveränderung eigentlich nur noch in den Kopf schießen  aber wozu gibt Datenbanken und XML ?


----------



## Spacerat (18. Dez 2009)

maki hat gesagt.:


> Wenn man eine SUID angibt, bedeutet das: Man kann Objekte zwischen verschiedenen Klassenversionen de-/serialisieren und die Anwendung ist dafür ausgelegt... da ist ein großes Risiko mit verbunden
> 
> Es ist ganz und gar kein guter Stil immer eine SUID zu haben, besonders wenn man eben nicht zwischen verschiedenen Versionen de-/serialisieren will, die Gefahr sollte selbsterklärend sein
> 
> ...


Naja... Wenn ich es mir recht überlege, ist da durchaus was dran. Vor allem dass man bei definierter SUID (bis auf eine Exception beim deserialisieren) gar nicht mehr merkt, das zwischen verschiedenen Versionen serialisiert wurde. Aber es ist doch eine Empfehlung von Sun, sie zu definieren. Darf man sich inzwischen schon aussuchen, an welche Konventionen man sich hält oder nicht? Mir geht diese Warnung im übrigen auch auf den Sender. Vorallem, wenn die Klasse niemals zum serialisieren gedacht ist. Was ich aber viel haarsträubender finde, ist, jemals irgendwo Warnungen unterdrücken zu müssen ([OT]... das geht mal direkt an GENERICS [/OT]). Da fragt man sich manchmal früher oder später, warum genau dort etwas unterdrückt werden musste und ob es nicht anders geht. Das gilt nicht nur für Java.


----------



## maki (18. Dez 2009)

> Aber es ist doch eine Empfehlung von Sun, sie zu definieren. Darf man sich inzwischen schon aussuchen, an welche Konventionen man sich hält oder nicht?


Ist leider nicht das erste mal dass man die Empfehlung von Sun ignorieren sollte, zB. in JPA 1.0 wurde empfohlen die Annotationen an die Getter/Setter zu machen, was auch quatsch ist und in JPA 2.0 korrigiert wurde, was aus J2EE geworden ist brauche ich ja nciht mehr zu erwähnen, mittlerweile orientieren sich die in einigen Punkten stark an Spring.

Das ist übrigebns nicht auf meinem Mist gewachsen, hab's aus Robert .C "Uncle Bob" Martins Buch "Clean Code"


----------

