gpt4 book ai didi

lambda - "Invalid lambda deserialization"当 lambda 用于接口(interface)实现时

转载 作者:行者123 更新时间:2023-12-04 00:08:05 26 4
gpt4 key购买 nike

我有一个带有 lambda 表达式的 Wicket 口项目。在用户单击后退按钮的一页上,我的应用程序崩溃:

java.lang.IllegalArgumentException: Invalid lambda deserialization
at x.y.z.MyPage$3.$deserializeLambda$(MyPage.java:1)

在页面类(我返回的地方)中,我使用 lambda 表达式来实现此接口(interface):
public interface Localizator extends Serializable {
String getLocalizedString(String key);
}

和 lambda:
protected void someMethod() {
localize((String key) -> getString(key));
}

当我将 lambda 更改为匿名类时,一切正常。在这种情况下我应该如何使用 lambda?

环境:Java 1.8.0_25、Netbeans 8.0.2、Wicket 6.17.0。

编辑:
这是使用 lambda 的真实(但简化)方法:
@Override
protected DataLoader createDataLoader() {

return new DataLoader(){

@Override
public List loadData() {
...
}

@Override
public List convertToTableRows(List data) {
return Converter.asRowList(
data,
(Record record) -> {...}, // this lambda is OK
(String key) -> getString(key)); // this lambda is crashing
}

@Override
public List filterTableRow() {
...
}

};
}

转换器类:
public class Converter implements Serializable { 
public static ArrayList asRowList(List data, OtherLoader loader, Localizator localizator){...}

DataLoader 还扩展了 Serializable。

最佳答案

启用 Serialization支持,拥有 interface延长 Serializable足够了。那时不需要进行额外的类型转换。您的代码可以序列化 lambda 表达式实例这一事实表明了这一点。它在反序列化时失败,这是一个类不兼容的指标,所以如果插入强制转换有帮助,很可能这是一个副作用,因为插入强制转换强制重新编译包含 lambda 表达式的类。

如果您想继续使用序列化的 lambda,您应该了解它的工作原理,如 the documentation of 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 的属性不匹配。这些特性可能会变得非常脆弱。
它们包括功能接口(interface)、捕获的参数和目标方法。在 lambda 表达式(而不是方法引用)的情况下,目标方法是定义类中的合成方法,具有编译器选择的未指定名称,甚至可能依赖于同一类中的其他 lambda 表达式,因为插入另一个表达式可能由于编号方案而导致名称更改。
与插入 serialVersionUID 的普通类不同。可能会告诉序列化框架它不应该关心明显的不一致,你不能告诉 lambda 表达式显示更多的健壮性。换句话说,一旦你序列化了应该持久化的 lambda 实例,你就不能改变它们的定义类。另见 this answer

关于lambda - "Invalid lambda deserialization"当 lambda 用于接口(interface)实现时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28946655/

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