截至 Java 14,@Serial 注释的用途是什么

What is the use of @Serial annotation as of Java 14

Java14在java.io包中引入了一个新的注解@Serial。它在 API 文档中的简要描述:

Indicates that an annotated field or method is part of the serialization mechanism defined by the Java Object Serialization Specification.

据我了解,注释用于编译时验证(类似于 @Override)以检查 serialization mechanism methods and fields are used correctly. What I don't understand, does the annotation affect the de/serialization itself as long as it is a part of the serialization mechanism? Or is it a first step to improve the de/serialization feature design in the way suggested with this comment?

So if it should be the whole picture, add them all: @Serializable, @NotSerializable, @Transient and make Serializable deprecated…

我对它的使用感到困惑,而且我还没有找到任何使用它的代码。您能否提供一个示例代码来突出显示未使用但应该使用注释时的问题?

What I don't understand, does the annotation affect the de/serialization itself

没有。它的保留是'source',所以编译后就丢弃了。字节码将不包含它的踪迹。它无法影响运行时行为(除了可能 compile-time 代码生成,这不会发生)。

@Override 一样,它是可选的,应该为一些 compile-time 问题提供保证,否则这些问题可能要到运行时才能被发现。

例如拼写错误serialVersionUID:

@Serial
private static final long seralVersionUID = 123L; // compile-time error, should be 'serialVersionUID'

或者访问修饰符错误

// compile-time error, must be private 
@Serial
public void writeObject(java.io.ObjectOutputStream out) throws IOException

基本上,带有此注释的内容必须与 JavaDoc 中提到的 7 个适用元素(5 个方法,2 个字段)的描述完全匹配。如果一个方法的签名不匹配,或者修饰符错误,你会在运行时序列化失败之前捕获问题。

此注释的存在纯粹是为了更好地进行 compile-time 类型检查。它以这种方式类似于 @Override 注释,它的存在纯粹是为了捕捉设计意图,以便人类和工具有更多的信息可以使用。 @Override 注释不会 使 一个方法声明覆盖另一个方法声明——这是由语言基于比较方法和方法之间的名称、签名和可访问性来处理的超类型。 @Override 所做的是断言“我认为这是一个覆盖,如果我弄错了,请以编译错误的形式告诉我。”它提醒代码的读者,这个方法对于 class.

来说并不是新方法

因为序列化使用了“魔法”方法和字段名(像readObject这样的方法不是任何接口的一部分,它们只是通过序列化神奇地赋予了意义),判断魔法是否有效是棘手的(方法不仅必须具有正确的名称和参数,而且必须具有正确的可访问性和 static-ness),很容易声明一个您认为要由序列化使用但序列化不同意的方法.

@Serial 注释可以让你做出类似的断言:你打算这是那些神奇的序列化成员之一(字段和方法),如果它与配置文件不匹配,编译器应该提醒你一个错误。并且给读者一个类似的提示,这个成员是要被序列化使用的。

大多数开发人员可能不会为应用程序和域代码操心。但是库作者可能会发现它是一种有用的方式,可以进行更强大的类型检查和更好地捕捉设计意图。