序列化的lambda和没有serialVersionUID? [英] serialized lambda and no serialVersionUID?

查看:196
本文介绍了序列化的lambda和没有serialVersionUID?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to learn how the serialization works with Java and its lastest version. I'm trying to serialize a lambda like this :

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

但我注意到我没有关于缺少 serialVersionUID <的警告/ code>变量。这是正常的吗?

But I notice that I have no warning about the absence of a serialVersionUID variable. Is it normal ?

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

I know it will be generated at the runtime however it is strongly recommended to define it : https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html


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

If a serializable class does not explicitly declare a serialVersionUID, then the serialization runtime will calculate a default serialVersionUID value for that class based on various aspects of the class, as described in the Java(TM) Object Serialization Specification. However, it is strongly recommended that all serializable classes explicitly declare serialVersionUID values, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations, and can thus result in unexpected InvalidClassExceptions during deserialization. Therefore, to guarantee a consistent serialVersionUID value across different java compiler implementations, a serializable class must declare an explicit serialVersionUID value. It is also strongly advised that explicit serialVersionUID declarations use the private modifier where possible, since such declarations apply only to the immediately declaring class--serialVersionUID fields are not useful as inherited members. Array classes cannot declare an explicit serialVersionUID, so they always have the default computed value, but the requirement for matching serialVersionUID values is waived for array classes.

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

What should I do ? How can I define it in my Lambda ?

谢谢

推荐答案

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

The serialVersionUID is only relevant to classes which generate a stream identifier. This is not the case if the serializable class has a writeReplace() method (also described in the Serializable documentation) that returns a substitute object of a different class, as such a representation is fully decoupled from the original class. This is what happens with serializable lambda instances, see SerializedLambda:


可序列化lambda的实现者,例如编译器或语言运行时库,应该确保实例正确反序列化。一种方法是确保 writeReplace 方法返回 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 的实例,最后在流上因此,该类有责任拥有稳定的序列化表示。不幸的是,这并不能保护您免受可能的不兼容性的影响。

So it’s an instance of SerializedLambda that ends up on the stream and thus the responsibility of that class to have a stable serialized representation. Unfortunately that doesn’t protect you from possible incompatibilities.

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

Upon deserialization, a synthetic method of the class defining the lambda expression will get called (compare to this and this answer) which will reject deserialization attempts which do not match an existing definition of a lambda expression within that class, whereas the matching may depend on subtle aspects of the lambda’s definition. Note that even recompiling the defining class with Eclipse rather than javac might break the Serialization compatibility.

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

Not also the security impacts of Serializable lambdas. Generally, I recommend to avoid using it.

这篇关于序列化的lambda和没有serialVersionUID?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆