序列化的 lambda 且没有serialVersionUID?

2024-05-01

我正在尝试了解 Java 及其最新版本的序列化如何工作。我正在尝试像这样序列化 lambda:

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

但我注意到我没有收到关于缺少serialVersionUID多变的。正常吗?

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

如果一个可序列化类没有显式声明一个serialVersionUID,那么序列化运行时将计算一个 基于各个方面的该类的默认serialVersionUID值 类的属性,如 Java(TM) 对象序列化中所述 规格。不过,强烈建议所有 可序列化类显式声明serialVersionUID值,因为 默认的serialVersionUID计算对类高度敏感 细节可能会因编译器实现而异,并且可以 因此会导致意外的 InvalidClassExceptions 反序列化。因此,要保证serialVersionUID一致 跨不同java编译器实现的值,可序列化 类必须声明显式的serialVersionUID 值。也是 强烈建议显式的serialVersionUID声明使用 尽可能使用 private 修饰符,因为此类声明仅适用于 立即声明类 --serialVersionUID 字段不是 作为继承成员有用。数组类不能显式声明 SerialVersionUID,因此它们始终具有默认的计算值,但是 免除匹配serialVersionUID值的要求 数组类。

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

Thanks


The serialVersionUID仅与生成的类相关流标识符 http://docs.oracle.com/javase/8/docs/api/java/io/ObjectStreamClass.html。如果可序列化类有一个,则情况并非如此writeReplace()方法(也描述于Serializable文档 http://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html)返回不同类的替代对象,因为这样的表示与原始类完全解耦。这就是可序列化 lambda 实例发生的情况,请参阅SerializedLambda http://docs.oracle.com/javase/8/docs/api/java/lang/invoke/SerializedLambda.html:

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

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

反序列化时,定义 lambda 表达式的类的合成方法将被调用(与this https://stackoverflow.com/a/28960234/2711488 and 这个答案 https://stackoverflow.com/a/28084460/2711488),这将拒绝与该类中 lambda 表达式的现有定义不匹配的反序列化尝试,而匹配可能取决于 lambda 定义的微妙方面。请注意,甚至使用 Eclipse 重新编译定义类而不是javac可能会破坏序列化兼容性。

也不是的安全影响Serializable lambdas https://stackoverflow.com/q/25443655/2711488。一般来说,我建议避免使用它。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

序列化的 lambda 且没有serialVersionUID? 的相关文章

随机推荐