我有一个包含lambda表达式的wicket项目。在一个页面上,当用户单击后退按钮时,我的应用程序会崩溃:
java.lang.IllegalArgumentException: Invalid lambda deserialization
at x.y.z.MyPage$3.$deserializeLambda$(MyPage.java:1)
在页面类(我返回的地方)中,我使用lambda表达式来实现这个接口:
public interface Localizator extends Serializable {
String getLocalizedString(String key);
}
而羔羊:
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还扩展了可序列化。
发布于 2015-03-10 09:36:50
要启用Serialization
支持,拥有一个interface
扩展Serializable
就足够了。没有必要再做一个额外的演员。这表现在代码可以序列化lambda表达式实例。反序列化失败了,因为反序列化是类不兼容的指示器,所以如果插入强制转换很可能会产生副作用,因为插入强制转换强制重新编译包含lambda表达式的类。
如果您想继续使用序列化的lambda,您应该了解它是如何工作的,正如SerializedLambda
中所解释的那样。
可序列化lambda的实现者(例如编译器或语言运行库)将确保实例正确反序列化。这样做的一种方法是确保
writeReplace
方法返回SerializedLambda
的实例,而不是允许进行默认序列化。SerializedLambda
有一个readResolve
方法,它在捕获类中寻找一个(可能是私有的)静态方法$deserializeLambda$(SerializedLambda)
,用它本身调用它作为第一个参数,并返回结果。实现$deserializeLambda$
的Lambda类负责验证SerializedLambda
的属性是否与该类实际捕获的lambda一致。
因此,当$deserializeLambda$
在异常情况下拒绝反序列化时,这意味着序列化lambda的属性与类中定义的已知可序列化lambda的属性不匹配。这些财产可能会变得非常脆弱。
它们包括函数接口、捕获的参数和目标方法。对于lambda表达式(而不是方法引用),目标方法是定义类中的合成方法,具有编译器选择的、未指定的名称,甚至可能依赖于同一类中的其他lambda表达式,因为插入另一个表达式可能会由于编号方案而导致名称更改。
与普通类不同的是,插入serialVersionUID
可能会告诉序列化框架它不应该关心明显的不一致,您不能告诉lambda表达式显示更强的健壮性。换句话说,一旦您已经序列化了应该持久化的lambda实例,就不能更改它们的定义类。另见这个答案
发布于 2021-02-17 13:48:40
这没有回答上面的问题,但是在搜索Invalid lambda deserialization in Flink
__时,这个线程首先弹出。
如果您在发布之前使用Proguard混淆
Serializable
类proguard.pro
来修复此错误,请参阅这个答案。在我自己的例子中,我实现了正式文件中建议的“Java8Lambda”设置,但是文档改变了,现在我缺少了在这里解释的新设置。
一般情况下,"lambda不能序列化“是什么意思:
.map(string -> (CustomClass) string)
CustomClass
不implement Serializable
,则不可序列化。若要使该类可序列化,请添加implements Serializable
,并添加SerialVersionUID
并确保该类的所有属性本身都可序列化。
https://stackoverflow.com/questions/28946655
复制相似问题