gpt4 book ai didi

java - 无法反序列化 lambda

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:34:24 25 4
gpt4 key购买 nike

作为一个小项目,我一直在尝试做一个小东西来读取序列化的 lambdas(本地或从 FTP)并调用它们的运行函数作为测试的一部分来试验 Windows 中的文件关联(即打开某些文件类型使用特定程序打开它们)等等,但无论我尝试什么,它似乎都无法正确反序列化。

lambda 是这样声明的

Runnable r = (Runnable & Serializable) () -> {
// blah blah
// made sure not to capture anything
};

并使用由 ObjectOutputStream 包裹的 [n optional] BufferedOutputStream 包裹的 FileOutputStream 进行序列化,没有问题。然而,当[在不同的项目中]反序列化时,它失败了,说它找不到包含序列化它的代码的封闭类。我尝试了各种方法,例如将它们包装在可序列化类中(w/serialVersionUID = 0L 用于测试目的)或定义一个扩展 Runnable 和 Serializable 的接口(interface),但无济于事。

是的,我知道序列化 lambda 并不是很好的做法(或者我们被告知),但我不确定如何将函数和子例程转换成我可以存储为文件或在一个FTP。如果这根本不是正确的方法,请告诉。

哦,我正在使用最新版本的 Eclipse Luna。

编辑:

像这样反序列化

File f = new File(somePath);
FileInputStream fish = new FileInputStream(f);
BufferedInputStream bos = new BufferedInputStream(fish); // not really necessary
ObjectInputStream ois = new ObjectInputStream(bos);
Runnable r = (Runnable) ois.readObject();
ois.close();
r.run();

最佳答案

如果没有定义对象的类,则无法反序列化对象。 lambda 表达式并没有改变这一点。

Lambda 表达式有点复杂,因为它们生成的运行时类不是定义它的类,但它们的定义类是保存 lambda 主体代码的类,在可序列化的 lambda 的情况下,反序列化支持方法是调用以验证和重新实例化 lambda 实例。

参见 SerializedLambda :

Implementors of serializable lambdas, such as compilers or language runtime libraries, are expected to ensure that instances deserialize properly. One means to do so is to ensure that the writeReplace method returns an instance of SerializedLambda, rather than allowing default serialization to proceed.

SerializedLambda has a readResolve method that looks for a (possibly private) static method called $deserializeLambda$(SerializedLambda) in the capturing class, invokes that with itself as the first argument, and returns the result. Lambda classes implementing $deserializeLambda$ are responsible for validating that the properties of the SerializedLambda are consistent with a lambda actually captured by that class.

因此,即使您的实例没有引用定义类中的合成方法(例如,在方法引用此类外部方法的情况下),反序列化仍然需要 $deserializeLambda$有意验证实例的正确性。


关于序列化 lambda 的“最佳实践”,请记住 lambda 表达式封装行为,而不是状态。存储行为总是意味着只存储某种引用并要求用于恢复它的代码实现关联的行为。如果您只是通过符号名称或只是存储来引用预期行为,那也会起作用,例如关联的 enum 值。

有关具有可序列化 lambda 的含义的更多信息,请参阅 this question .

关于java - 无法反序列化 lambda,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28079307/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com