序列化 lambda 而没有 serialVersionUID?
serialized lambda and no serialVersionUID?
我正在尝试了解序列化如何与 Java 及其最新版本一起工作。我正在尝试像这样序列化一个 lambda :
Runnable r = (Runnable & Serializable)() -> {System.out.println("This is a test");};
但我注意到我没有关于 serialVersionUID
变量缺失的警告。正常吗?
我知道它会在运行时生成,但强烈建议定义它:https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html
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 中定义它?
谢谢
serialVersionUID
仅与生成 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
:
的 classes 相关
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
的一个实例,它最终出现在流中,因此 class 有责任拥有一个稳定的序列化表示。不幸的是,这并不能保护您免受可能的不兼容性。
反序列化时,将调用定义 lambda 表达式的 class 的合成方法(与 this and 相比),它将拒绝与 lambda 表达式的现有定义不匹配的反序列化尝试在 class 中,而匹配可能取决于 lambda 定义的微妙方面。请注意,即使使用 Eclipse 而不是 javac
重新编译定义 class 也可能会破坏序列化兼容性。
也不是 security impacts of Serializable
lambdas。一般来说,我建议避免使用它。
我正在尝试了解序列化如何与 Java 及其最新版本一起工作。我正在尝试像这样序列化一个 lambda :
Runnable r = (Runnable & Serializable)() -> {System.out.println("This is a test");};
但我注意到我没有关于 serialVersionUID
变量缺失的警告。正常吗?
我知道它会在运行时生成,但强烈建议定义它:https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html
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 中定义它?
谢谢
serialVersionUID
仅与生成 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
:
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 ofSerializedLambda
, rather than allowing default serialization to proceed.
所以它是 SerializedLambda
的一个实例,它最终出现在流中,因此 class 有责任拥有一个稳定的序列化表示。不幸的是,这并不能保护您免受可能的不兼容性。
反序列化时,将调用定义 lambda 表达式的 class 的合成方法(与 this and javac
重新编译定义 class 也可能会破坏序列化兼容性。
也不是 security impacts of Serializable
lambdas。一般来说,我建议避免使用它。