序列化的lambda和没有serialVersionUID?

Tho*_*ous 6 java lambda serialization serialversionuid java-8

我正在尝试学习序列化如何与Java及其最新版本一起使用.我正在尝试序列化这样的lambda:

Runnable r = (Runnable & Serializable)() -> {System.out.println("This is a test");};
Run Code Online (Sandbox Code Playgroud)

但我注意到我没有关于缺少serialVersionUID变量的警告.这是正常的吗?

我知道它将在运行时生成,但强烈建议您定义它:https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html

如果可序列化类未显式声明serialVersionUID,则序列化运行时将基于类的各个方面计算该类的默认serialVersionUID值,如Java(TM)对象序列化规范中所述.但是,强烈建议所有可序列化类显式声明serialVersionUID值,因为默认的serialVersionUID计算对类细节高度敏感,这些细节可能因编译器实现而异,因此在反序列化期间可能导致意外的InvalidClassExceptions.因此,为了保证跨不同java编译器实现的一致的serialVersionUID值,可序列化类必须声明显式的serialVersionUID值.强烈建议显式serialVersionUID声明尽可能使用private修饰符,因为此类声明仅适用于立即声明的类 - serialVersionUID字段作为继承成员无用.数组类不能声明显式的serialVersionUID,因此它们始终具有默认的计算值,但是对于数组类,不需要匹配serialVersionUID值.

我该怎么办 ?如何在Lambda中定义它?

谢谢

Hol*_*ger 6

serialVersionUID是仅向生成的类相关的流标识符.如果可序列化类具有返回不同类的替换对象的writeReplace()方法(也在Serializable文档中描述),则不是这种情况,因为这样的表示与原始类完全分离.这是可序列化的lambda实例所发生的情况,请参阅SerializedLambda:

可序列化lambda的实现者,例如编译器或语言运行库,应该确保实例正确地反序列化.一种方法是确保writeReplace方法返回实例SerializedLambda,而不是允许默认序列化继续进行.

因此,它的一个实例SerializedLambda最终会出现在流上,因此该类的责任是拥有稳定的序列化表示.不幸的是,这并不能保护您免受可能的不兼容性的影响.

在反序列化时,将调用定义lambda表达式的类的合成方法(与此答案相比),这将拒绝与该类中的lambda表达式的现有定义不匹配的反序列化尝试,而匹配可能取决于lambda定义的微妙方面.请注意,即使使用Eclipse重新编译定义类javac也可能会破坏序列化兼容性.

不是lambdas安全影响Serializable.一般来说,我建议避免使用它.