Die Java-Sprache profitierte sehr davon, dass sie enums hinzugefügt wurde; aber leider funktionieren sie nicht gut, wenn serialisierte Objekte zwischen Systemen mit unterschiedlichen Code-Ebenen gesendet werden.
Beispiel: Angenommen, Sie haben zwei Systeme A und B. Beide starten mit den gleichen Code-Ebenen, aber irgendwann beginnen die Code-Aktualisierungen zu verschiedenen Zeitpunkten. Nun gehe davon aus, dass es einige gibt %Vor%
Und es gibt andere Objekte, die Referenzen auf Konstanten dieser Enumeration behalten. Diese Objekte werden serialisiert und von A nach B oder umgekehrt gesendet. Bedenke nun, dass B eine neuere Version von Whatever
hat %Vor%Dann:
%Vor%wird instanziiert ...
%Vor%und dann serialisiert und an A gesendet (zum Beispiel als Ergebnis eines RMI-Aufrufs). Was ist schlecht, denn jetzt wird bei der Deserialisierung auf A ein Fehler auftreten: A kennt die Whatever enum-Klasse, aber in einer Version, die nicht SECOND hat.
Wir haben das auf die harte Tour gemerkt; und jetzt bin ich sehr bestrebt, Enums für Situationen zu verwenden, die eigentlich "perfekt für Enums" wären; einfach weil ich weiß, dass ich ein existierendes enum später nicht einfach erweitern kann.
Nun frage ich mich: Gibt es (gute) Strategien, um solche Kompatibilitätsprobleme mit Enums zu vermeiden? Oder muss ich wirklich zurück zu "Prä-Enum" Zeiten gehen; und verwende keine Enums, sondern musst dich auf eine Lösung verlassen, bei der ich überall einfache Strings verwende?
Update: Bitte beachten Sie, dass die Verwendung der serialversionuid hier überhaupt nicht hilft. Dieses Ding hilft dir nur dabei, eine inkompatible Veränderung "offensichtlicher" zu machen. Aber der Punkt ist: Es ist mir egal, warum die Deserialisierung fehlschlägt - weil ich es vermeiden muss. Und ich bin auch nicht in der Lage, unsere Art der Serialisierung unserer Objekte zu verändern. Wir machen RMI; und wir serialisieren zu binär; Ich habe keine Möglichkeit, das zu ändern.
Nachdem ich zu verschiedenen Lösungen hin und her gegangen bin, habe ich eine Lösung gefunden, die auf dem Vorschlag von @GuiSim basiert: Man kann eine Klasse erstellen, die einen Enum-Wert enthält. Diese Klasse kann
Wie @Jesper in den Kommentaren erwähnt, würde ich etwas wie JSON für Ihre dienststellenübergreifende Kommunikation empfehlen. Dadurch können Sie besser steuern, wie unbekannte Enum-Werte gehandhabt werden.
Zum Beispiel könnt ihr mit dem immer tollen Jackson das Deserialisierungsfunktionen READ_UNKNOWN_ENUM_VALUES_AS_NULL
oder READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE
. Beides ermöglicht Ihrer Anwendungslogik, unbekannte Enum-Werte so zu verarbeiten, wie Sie es für richtig halten.
Beispiel (direkt aus dem Jackson-Dokument)
%Vor%Tags und Links java serialization enums