Lambda kann nicht deserialisiert werden

8

Genau wie ein kleines Projekt habe ich versucht, eine kleine Sache zu machen, die serialisierte Lambdas (lokal oder von einem FTP) liest und ihre Lauffunktionen als Teil eines Tests startet, um mit Dateizuordnungen in Windows zu experimentieren (dh zu öffnen bestimmte Dateitypen öffnet sie mit einem bestimmten Programm) und was auch immer, aber egal was ich versuche, es scheint nie richtig zu deserialisieren.

Das Lambda wurde so erklärt

%Vor%

und serialisiert mit einem FileOutputStream, der von einem [n optional] BufferedOutputStream umhüllt wird, der von einem ObjectOutputStream ohne Problem umschlossen wird. Wenn es jedoch [in einem anderen Projekt] deserialisiert wird, schlägt es fehl und sagt, dass es die umschließende Klasse, die den Code für die Serialisierung enthielt, nicht finden konnte. Ich habe verschiedene Dinge versucht, wie sie in eine serialisierbare Klasse (w / serialVersionUID = 0L für Testzwecke) zu wickeln oder eine Schnittstelle zu definieren, die Runnable und Serializable erweitert, aber ohne Erfolg.

Ja, ich bin mir bewusst, dass das Serialisieren von Lambdas keine wirklich gute Übung ist (oder so wird es gesagt), aber ich bin mir nicht sicher, wie ich Funktionen und Subroutinen in etwas umwandeln kann, das ich als Datei speichern kann ein FTP. Wenn das überhaupt nicht der richtige Weg ist, sag es.

Oh, ich benutze Eclipse Luna von der neusten Version.

Bearbeiten:

Deserialisiert wie folgt

%Vor%     
Mona the Monad 22.01.2015, 00:16
quelle

2 Antworten

11

Sie können ein Objekt nicht deserialisieren, ohne dass die Klasse es definiert. Dies hat sich bei Lambda-Ausdrücken nicht geändert.

Lambda-Ausdrücke sind etwas komplexer, da ihre generierte Laufzeitklasse nicht die Klasse ist, die sie definiert hat, sondern ihre definierende Klasse diejenige ist, die den Code des Lambda-Körpers enthält, und im Fall serialisierbarer Lambdas eine Deserialisierungs-Unterstützungsmethode zur Validierung und erneuten Instanziierung der Lambda-Instanz aufgerufen.

Siehe SerializedLambda :

  

Implementierungen serialisierbarer Lambdas, wie Compiler oder Language Runtime-Bibliotheken, stellen sicher, dass Instanzen korrekt deserialisiert werden. Eine Möglichkeit besteht darin, sicherzustellen, dass die Methode writeReplace eine Instanz von SerializedLambda zurückgibt, anstatt zuzulassen, dass die Standardserialisierung fortgesetzt wird.

     

SerializedLambda hat eine readResolve -Methode, die nach einer (möglicherweise privaten) statischen Methode mit dem Namen $deserializeLambda$(SerializedLambda) in der Capturing-Klasse sucht, diese mit sich selbst als erstem Argument aufruft und das Ergebnis zurückgibt. Lambda-Klassen, die $deserializeLambda$ implementieren, sind dafür verantwortlich, dass die Eigenschaften von SerializedLambda mit einem tatsächlich von dieser Klasse erfassten Lambda übereinstimmen.

Selbst wenn Ihre Instanz sich nicht auf eine synthetische Methode innerhalb der definierenden Klasse bezieht (z. B. im Fall einer Methodenreferenz auf eine Methode außerhalb dieser Klasse), erfordert die Deserialisierung immer noch $deserializeLambda$ für die Validierung der Korrektheit der Instanz , absichtlich.

In Bezug auf die "gute Praxis" der Serialisierung von Lambda ist zu beachten, dass Lambda-Ausdrücke Verhalten einkapseln, nicht den Status. Speicherverhalten bedeutet immer, nur eine Art von Referenz zu speichern und den Code, der es wiederherstellen soll, zu benötigen, um das zugehörige Verhalten implementiert zu haben. Das würde genauso gut funktionieren, wenn Sie sich gerade auf das beabsichtigte Verhalten durch einen symbolischen Namen bezogen oder einfach nur gespeichert haben, z. assoziierte enum -Werte.

Mehr über die Auswirkungen von serialisierbaren Lambdas erfahren Sie in dieser Frage .

    
Holger 22.01.2015, 08:48
quelle
4

Wenn Sie ein Objekt deserialisieren, muss der Code, der die Deserialisierung durchführt, über die Klasse des serialisierten Objekts Bescheid wissen. Sie können kein beliebiges Lambda serialisieren und es in einer anderen Codebasis deserialisieren.

Der Serialisierungs- und Deserialisierungscode muss sich mehr oder weniger in derselben Codebasis befinden oder muss mindestens eine Abhängigkeit von dem Code aufweisen, der das ursprüngliche Lambda enthält.

    
Louis Wasserman 22.01.2015 04:24
quelle

Tags und Links