16 Stimmen

Wie kann man die Konsistenz von Enums in der Java-Serialisierung sicherstellen?

Wenn ich ein Objekt serialisiere, kann ich den serialVersionUID-Mechanismus auf Klassenebene verwenden, um die Kompatibilität der beiden Typen zu gewährleisten.

Was passiert jedoch, wenn ich Felder mit Enum-Werten serialisiere? Gibt es eine Möglichkeit, sicherzustellen, dass der Enum-Typ zwischen Serialisierung und Deserialisierung nicht verändert wurde?

Angenommen, ich habe ein Enum wie OperationResult {SUCCESS, FAIL} und ein Feld namens "result" in einem Objekt, das serialisiert wird. Wie kann ich sicherstellen, dass das Ergebnis bei der Deserialisierung des Objekts auch dann noch korrekt ist, wenn jemand die beiden Werte böswillig vertauscht? (Angenommen, die Aufzählung wird an anderer Stelle als statische Aufzählung deklariert)

Ich frage mich das nur aus Neugier - ich verwende eine Authentifizierung auf Jar-Ebene, um Manipulationen zu verhindern.

22voto

Chris Dennett Punkte 21894

Von: http://www.theserverside.com/news/thread.tss?thread_id=50190#265205

Die Designer von enum f dass es keinen Anwendungsfall gibt, der eine neue enum-Objekte zur Laufzeit zu erstellen. Sie nahmen sorgfältig darauf geachtet, dies nicht zuzulassen.

Es sieht daher so aus, als ob Enum-Objekte nicht vollständig serialisiert und deserialisiert werden können. Auch von http://java.sun.com/javase/6/docs/platform/serialization/spec/serial-arch.html#6469 :

Enum-Konstanten sind se anders serialisiert als gewöhnliche serialisierbare oder externalisierbare Objekte. Die serialisierte Form einer Enum-Konstante besteht nur aus ihrem Namen; die Feld Feldwerte der Konstante sind nicht in der Form. Um eine Enum-Konstante zu serialisieren Konstante zu serialisieren, schreibt ObjectOutputStream den von der Enum-Konstante zurückgegebenen Wert Konstante zurückgegeben wird. Um zu deserialisieren einer Enum-Konstante liest ObjectInputStream den Namen der Konstante aus dem Stream; die deserialisierte Konstante wird dann durch Aufruf der Methode java.lang.Enum.valueOf-Methode erhalten, wobei der den Enum-Typ der Konstante zusammen mit den empfangenen Konstantennamen als Argumente. Wie andere serialisierbare oder externalisierbare Objekte, können Enum-Konstanten als Ziele von back Referenzen fungieren, die später im dem Serialisierungsstrom erscheinen.

Das Verfahren, mit dem serialisiert werden jedes klassenspezifische writeObject, readO writeReplace- und readResolve-Methoden die von Enum-Typen definiert werden, werden ignoriert während der Serialisierung und Deserialisierung ignoriert. In ähnlicher Weise werden alle serialPersistentFields oder serialVe ebenfalls ignoriert - alle Enum-Typen haben eine feste serialVersionUID von 0L. Dokumentieren von serialisierbaren Feldern und Daten für Enum-Typen ist unnötig, [ ] Typ der gesendeten Daten gibt.

5voto

meriton Punkte 65030

Enums werden bei der Deserialisierung durch Lesezeichen ersetzt. Das Zitieren der Serialisierung Versionshinweise für die Version 1.5:

Die Regeln für serielle Instanz unterscheiden sich von denen für Serialisierung eines "normalen" serialisierbaren Objekts: Die serialisierte Form einer Enum Instanz besteht nur aus ihrem enum konstanten Namen, zusammen mit Informationen die ihren Basis-Enum-Typ identifizieren. Auch das Deserialisierungsverhalten unterscheidet sich die Klasseninformation wird verwendet, um um die entsprechende Enum-Klasse zu finden, und die Methode Enum.valueOf wird aufgerufen mit dieser Klasse und der erhaltenen Konstante Namen aufgerufen, um die Enum Konstante zurückzugeben.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X