1. Introduction

In this quick tutorial, we’ll take a look at the new @Serial annotation introduced with Java 14.

Similarly to @Override, this annotation is used in combination with the serial lint flag to perform compile-time checks for the serialization-related members of a class.

Although the annotation is already available as per build 25, the lint check has yet to be released.

2. Usage

Let’s start by annotating with @Serial any of the seven serialization-related methods and fields:

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;
    }

}

After that, we need to compile our class with the serial lint flag:

javac -Xlint:serial MySerialClass.java

The compiler will then check the signatures and the types of the annotated members and issue a warning if they don’t match the expected ones.

Furthermore, the compiler will also throw an error if @Serial is applied:

  • when a class is not implementing the Serializable interface:
public class MyNotSerialClass {
    @Serial 
    private static final long serialVersionUID = 1; // Compilation error
}
public enum MyEnum { 
    @Serial 
    private void readObjectNoData() throws ObjectStreamException {} // Compilation error 
}
  • to writeObject(), readObject(), readObjectNoData() and serialPersistentFields in an Externalizable class since those classes use different serialization methods:
public class MyExternalizableClass implements Externalizable {
    @Serial 
    private void writeObject(ObjectOutputStream stream) throws IOException {} // Compilation error 
}

3. Conclusion

This short article went through the new @Serial annotation usage.

As always, all the code in the article is available over on GitHub.