it-swarm.com.de

Warum braucht Java eine serialisierbare Schnittstelle?

Wir arbeiten intensiv mit der Serialisierung und müssen für jedes von uns verwendete Objekt ein serialisierbares Tag angeben, das ist eine Belastung. Vor allem, wenn es sich um einen 3rd-Party-Kurs handelt, den wir nicht wirklich ändern können.

Die Frage ist: da Serializable eine leere Schnittstelle ist und Java eine robuste Serialisierung bietet, sobald Sie implements Serializable hinzugefügt haben - warum haben sie nicht alles serialisierbar gemacht und das ist es? 

Was vermisse ich?

110
Yoni Roit

Die Serialisierung ist mit Fallen behaftet. Die Unterstützung der automatischen Serialisierung dieses Formulars macht die Klassen-Interna zum Bestandteil der öffentlichen API (deshalb gibt Ihnen javadoc die persistenten Klassenformen ).

Für eine langfristige Persistenz muss die Klasse in der Lage sein, dieses Formular zu decodieren, was die Änderungen einschränkt, die Sie am Klassendesign vornehmen können. Dies bricht die Einkapselung.

Die Serialisierung kann auch zu Sicherheitsproblemen führen. Durch die Möglichkeit, jedes Objekt, auf das es verweist, serialisieren zu können, kann eine Klasse auf Daten zugreifen, zu denen sie normalerweise nicht in der Lage wäre (durch Parsen der resultierenden Byte-Daten).

Es gibt andere Probleme, z. B. die serialisierte Form innerer Klassen, die nicht genau definiert sind.

Die Serialisierung aller Klassen würde diese Probleme verschlimmern. Check out Effektive Java Second Edition , insbesondere Punkt 74: Serializable sinnvoll umsetzen.

112
McDowell

Ich denke, dass sowohl Java- als auch .NET-Benutzer diesmal falsch gehandelt haben. Es wäre besser, alles standardmäßig serialisierbar zu machen und muss nur diejenigen Klassen markieren, die stattdessen nicht sicher serialisiert werden können.

In Smalltalk (einer Sprache, die in den 70er Jahren erstellt wurde) ist jedes Objekt beispielsweise standardmäßig serialisierbar. Ich habe keine Ahnung, warum dies in Java nicht der Fall ist, in Anbetracht der Tatsache, dass die große Mehrheit der Objekte sicher serialisiert werden kann und nur einige wenige. 

Das Markieren eines Objekts als serialisierbar (mit einer Schnittstelle) macht das Objekt nicht auf magische Weise serialisierbar. es war die ganze Zeit serialisierbar. Ein wirklich guter Grund für die Serialisierung, wie sie jetzt ist.

Ich denke, es war entweder eine schlechte Entscheidung der Designer, oder die Serialisierung war ein nachträglicher Einfall, oder die Plattform war niemals bereit, die Serialisierung aller Objekte sicher und konsistent durchzuführen. 

31
Pop Catalin

Nicht alles ist echt serialisierbar. Nehmen Sie zum Beispiel eine Netzwerk-Socket-Verbindung. Sie könnten die Daten/den Status Ihres Socket-Objekts serialisieren, aber das Wesen einer aktiven Verbindung würde verloren gehen.

19
Joel Coehoorn

Die Hauptfunktion von Serializable in Java besteht darin, alle anderen Objekte standardmäßig nicht zu serialisieren. Die Serialisierung ist ein sehr gefährlicher Mechanismus, insbesondere in der Standardimplementierung. Daher ist es wie die Freundschaft in C++ standardmäßig deaktiviert, auch wenn es etwas kostet, seriell zu machen.

Die Serialisierung fügt Einschränkungen und potenzielle Probleme hinzu, da die Kompatibilität der Strukturen nicht gewährleistet ist. Es ist gut, dass es standardmäßig deaktiviert ist.

Ich muss zugeben, dass ich sehr wenige nicht-triviale Klassen gesehen habe, bei denen Standardserialisierung das tut, was ich will. Besonders bei komplexen Datenstrukturen. Die Mühe, die Sie für die Erstellung der Serializble-Klasse aufwenden müssen, hat also einen erheblichen Aufwand für das Hinzufügen der Benutzeroberfläche zur Folge. 

13
Uri

Für einige Klassen, insbesondere für diejenigen, die etwas Physischeres darstellen, z. B. eine Datei, ein Socket, ein Thread oder eine DB-Verbindung, macht es absolut keinen Sinn, Instanzen zu serialisieren. Für viele andere ist die Serialisierung möglicherweise problematisch, weil sie Eindeutigkeitsbeschränkungen zerstört oder Sie einfach dazu zwingt, mit Instanzen verschiedener Versionen einer Klasse umzugehen, die Sie möglicherweise nicht möchten.

Es wäre vielleicht besser gewesen, alles standardmäßig serialisierbar zu machen und Klassen über ein Keyword- oder Marker-Interface nicht serialisierbar zu machen - aber dann würden diejenigen, die diese Option verwenden sollten, wahrscheinlich nicht darüber nachdenken. So wie es ist, wenn Sie Serializable implementieren müssen, wird Ihnen dies durch eine Ausnahme mitgeteilt.

8

Ich denke, es war jedoch wichtig sicherzustellen, dass Sie als Programmierer wissen, dass Ihr Objekt serialisiert werden kann.

4
Milhous

Anscheinend war in einigen Vorentwürfen alles serialisierbar, aber aus Sicherheits- und Korrektheitsgründen endete das endgültige Design, wie wir alle wissen.

Quelle: Warum müssen Klassen Serializable implementieren, um in einen ObjectOutputStream geschrieben zu werden? .

3
cic

Wenn Sie ausdrücklich angeben müssen, dass Instanzen einer bestimmten Klasse serialisierbar sind, müssen Sie darüber nachdenken, ob Sie dies zulassen. Bei einfachen Wertobjekten ist die Serialisierung trivial, aber in komplexeren Fällen müssen Sie die Dinge wirklich durchdenken.

Indem Sie sich nur auf die standardisierte Serialisierungsunterstützung der JVM verlassen, setzen Sie sich allen möglichen bösen Versionsproblemen aus.

Einzigartigkeit, Verweise auf "echte" Ressourcen, Zeitgeber und viele andere Arten von Artefakten sind KEINE Kandidaten für die Serialisierung.

1

Lesen Sie dies, um die serialisierbare Schnittstelle zu verstehen und warum wir nur wenige Klassen serialisierbar machen sollten. Außerdem achten wir darauf, dass Sie ein vorübergehendes Schlüsselwort verwenden, falls wir einige Felder aus dem Speichervorgang entfernen möchten.

http://www.codingeek.com/Java/io/object-streams-serialization-deserialization-Java-example-serializable-interface/

1
Hitesh Garg

Nun, meine Antwort ist, dass dies keinen guten Grund hat. Und aus Ihren Kommentaren kann ich ersehen, dass Sie das bereits gelernt haben. Andere Sprachen versuchen glücklich, alles zu serialisieren, das nicht in einen Baum springt, nachdem Sie auf 10 gezählt haben. 

Grundsätzlich müssen Sie also alle Eigenschaften Ihrer 3. Klasse selbst lesen. Oder, wenn dies eine Option für Sie ist: dekompilieren, das verdammte Schlüsselwort dort ablegen und neu kompilieren.

0
nes1983

Obwohl ich mit den in anderen Antworten genannten Punkten übereinstimme, besteht das eigentliche Problem in der Deserialisierung: Wenn sich die Klassendefinition ändert, besteht ein echtes Risiko, dass die Deserialisierung nicht funktioniert. Bestehende Felder nie zu ändern, ist für den Autor einer Bibliothek eine ziemlich große Verpflichtung! Die Aufrechterhaltung der API-Kompatibilität ist anstrengend genug.

0
CurtainDog

Es gibt einige Dinge in Java, die einfach nicht serialisiert werden können, da sie laufzeitabhängig sind. Dinge wie Streams, Threads, Laufzeit, Etc. und sogar einige GUI-Klassen (die mit dem zugrunde liegenden Betriebssystem verbunden sind) können nicht serialisiert werden.

0
mallik

Eine Klasse, die in einer Datei oder einem anderen Medium gespeichert werden muss, muss die serialisierbare Schnittstelle implementieren, damit JVM das Klassenobjekt serialisieren kann .. Warum die Objektklasse nicht serialisiert wird, muss keine der Klassen die Schnittstelle implementieren Schließlich serialisiert JVM die Klasse nur dann, wenn ich ObjectOutputStream verwende, was bedeutet, dass sich das Steuerelement immer noch in meinen Händen befindet, um die JVM serialisieren zu lassen.

Der Grund, warum die Objektklasse nicht standardmäßig serialisiert werden kann, da die Klassenversion das Hauptproblem ist. Daher muss jede an Serialisierung interessierte Klasse explizit als Serializable gekennzeichnet werden und eine Versionsnummer serialVersionUID angeben.

Wenn serialVersionUID nicht angegeben wird, erhalten wir unerwartete Ergebnisse, während das Objekt deserialisiert wird. Aus diesem Grund wirft JVM InvalidClassException wenn serialVersionUID nicht überein. Daher muss jede Klasse Serializable interface implementieren und serialVersionUID bereitstellen, um sicherzustellen, dass die an beiden Enden präsentierte Klasse identisch ist.

0