1.简介

在本文中,我们将介绍Java 14引入的新@Serial注解

@Override类似,此注解与*-Xlint*结合使用,以对类的与序列化相关的成员执行编译时检查。

尽管@Serial注解已在内部版本25中可用,但尚未发布支持-Xlint的版本。

2. 用法

让我们首先用@Serial注释与序列化相关的方法和字段:

public class SerialClass {
    @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;
    }
}

然后,我们需要使用*-Xlint*来编译我们的类

javac -Xlint:serial SerialClass.java

如果使用Maven的maven-compiler-plugin插件:

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>3.8.1</version>
      <configuration>
        <source>14</source>
        <target>14</target>
        <compilerArgs>
          <arg>-Xlint:serial</arg>
        </compilerArgs>
      </configuration>
    </plugin>
  </plugins>
</build>

然后,编译器将检查带注释的成员变量的类型,并在它们与预期成员不匹配时发出警告。

让我们来看下面的几个示例:

  • 当类未实现Serializable接口时
public class NotSerialClass {
    @Serial
    private static final long serialVersionUID = 1;
}

  • 无效的地方-例如在枚举中的序列化方法
public enum SerialEnum {
    TEST;

    @Serial
    private void readObjectNoData() throws ObjectStreamException {} 
}
  • 在实现Externalizable中的注解writeObject()readObject()readObjectNoData()serialPersistentFields方法,因为这些类使用不同的序列化方法:
public class ExternalizableClass implements Externalizable {
    @Serial
    private void writeObject(ObjectOutputStream stream) throws IOException {} 

    @Override
    public void writeExternal(ObjectOutput out) throws IOException {

    }

    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException   {

    }
}

3. 总结

本文介绍了新的*@Serial*注解的用法。

与往常一样,可以在GitHub上获得代码示例。