无法反序列化lambda
作为一个小项目,我一直在尝试做一个小事,它可以读取序列化的lambda(从本地或从FTP)并调用它们的运行函数作为测试的一部分,以测试Windows中的文件关联(即打开某些文件类型)使用特定程序打开它们),但不管如何,无论如何,它似乎从未正确地反序列化。
lambda被这样声明
Runnable r = (Runnable & Serializable) () -> { // blah blah
// made sure not to capture anything
};
并使用由ObjectOutputStream包装的[n可选]
BufferedOutputStream包装的FileOutputStream进行序列化,而不会出现问题。但是,在[在另一个项目中]反序列化时,它失败,表示找不到包含序列化它的代码的封闭类。我尝试了各种方法,例如将它们包装在可序列化的类中(出于测试目的,w
/ serialVersionUID = 0L)或定义扩展Runnable和Serializable的接口,但无济于事。
是的,我知道序列化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
:
可序列化lambda的实现者(例如编译器或语言运行时库)应确保实例正确反序列化。这样做的
writeReplace
一种方法是确保该方法返回的实例SerializedLambda
,而不是允许进行默认序列化。
SerializedLambda
有一个readResolve
方法寻找$deserializeLambda$(SerializedLambda)
在捕获类中调用的(可能是私有的)静态方法,以其本身作为第一个参数调用该方法,并返回结果。实现的Lambda类$deserializeLambda$
负责验证的属性SerializedLambda
是否与该类实际捕获的Lambda一致。
因此,即使您的实例未引用定义类内部的综合方法(例如,在方法引用此类之外的方法的情况下),反序列化仍然需要$deserializeLambda$
有意地验证实例的正确性。
关于序列化lambda的“最佳实践”,请记住,lambda表达式封装 行为
而不是状态。存储行为始终意味着仅存储某种参考,并且需要用于恢复它的代码来实现相关的行为。如果您只是通过符号名称或存储(例如关联的enum
值)来引用预期的行为,那也将起作用。
以上是 无法反序列化lambda 的全部内容, 来源链接: utcz.com/qa/402380.html