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

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

No. Its retention is 'source', so it's discarded after compilation. The bytecode will contain no trace of it. It has no way to influence runtime behaviour (besides possibly compile-time code generation, which does not happen).

Like @Override, it is optional and is supposed to give some compile-time assurance for problems which might otherwise not be caught until runtime.

For example, misspelling serialVersionUID:

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

Or the wrong access modifier

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

Basically, something annotated with this must exactly match the descriptions of the 7 applicable elements mentioned in the JavaDoc (5 methods, 2 fields). If the signature of a method does not match, or the modifiers are wrong, you will catch the problem before serialization fails at runtime.


This annotation exists purely to engage better compile-time type checking. It is analogous in this way to the @Override annotation, which exists purely to capture design intent, so that humans and tools have more information to work with. The @Override annotation does not make a method declaration an override of another -- that is handled by the language based on comparing names, signatures, and accessibility between the method and methods in the supertype(s). What @Override does is assert that "I think this is an override, if I am mistaken, please tell me in the form of a compilation error." And it serves as notice to readers of the code that this method is not new with this class.

Because serialization uses "magic" method and field names (methods like readObject are not part of any interface, they are just magically given significance by serialization), and the determination of whether the magic works is tricky (methods must not only have the right name and arguments, but the right accessibility and static-ness), it is easy to declare a method that you think is meant to be used by serialization, but for which serialization doesn't agree.

The @Serial annotation lets you make a similar kind of assertion: that you intend that this is one of those magic serialization members (fields and methods), and if it does not match the profile, the compiler should alert you with an error. And it provides a similar hint to readers that this member is going to be used by serialization.

Most developers probably won't bother with this for application and domain code. But library authors may find it useful as a way to engage stronger type checking and better capture design intent.