Contents

Java14中的 @Serial注解指南

Contents

1. 简介

在本快速教程中,我们将了解Java 14 引入的新*@Serial注解。 与@Override*类似,此注释与串行 lint 标志结合使用,以对类的序列化相关成员 执行编译时检查。

尽管根据 build 25 已经可以使用注释,但 lint 检查 尚未发布。

2. 用法

让我们从使用*@Serial*注释七个与序列化相关的方法和字段中的任何一个开始:

public class MySerialClass implements Serializable {
    @Serial
    private static final ObjectStreamField[] serialPersistentFields = null;

    @Serial
    private static final long serialVersionUID = 1;

    @Serial
    private void writeObject(ObjectOutputStream stream) throws IOException {
        // ...
    }

    @Serial
    private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
        // ...
    }
    @Serial
    private void readObjectNoData() throws ObjectStreamException {
        // ...
    }
    @Serial
    private Object writeReplace() throws ObjectStreamException {
        // ...
        return null;
    }
    @Serial
    private Object readResolve() throws ObjectStreamException {
        // ...
        return null;
    }
}

之后,我们需要使用串行 lint 标志编译我们的类

javac -Xlint:serial MySerialClass.java

然后编译器将检查签名和带注释的成员的类型,如果它们与预期的不匹配,则会发出警告。 此外,如果应用了*@Serial*,编译器也会抛出错误:

  • 当一个类没有实现Serializable接口时:
public class MyNotSerialClass {
    @Serial 
    private static final long serialVersionUID = 1; // Compilation error
}
  • 这将是无效的——例如枚举的任何序列化方法,因为它们被忽略
public enum MyEnum { 
    @Serial 
    private void readObjectNoData() throws ObjectStreamException {} // Compilation error 
}
  • writeObject()readObject()readObjectNoData()serialPersistentFields放在Externalizable 类中,因为这些类使用不同的序列化方法:
public class MyExternalizableClass implements Externalizable {
    @Serial 
    private void writeObject(ObjectOutputStream stream) throws IOException {} // Compilation error 
}