Java 14 introduces a new annotation @Serial
in the java.io
package. Its brief description in the API docs:
Indicates that an annotated field or method is part of the serialization mechanism defined by the Java Object Serialization Specification.
As far as I understand the annotation is used for the compile-time validation (similarly to @Override
) to check whether the 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…
I am confused of its use and I haven't found any code using it. Would you provide a sample code highlighting the issues when the annotation is not used but should be?
Java annotations are metadata (data about data) for our program source code. They provide additional information about the program to the compiler but are not part of the program itself. These annotations do not affect the execution of the compiled program.
The Java Specification Request JSR-175 introduced the general-purpose annotation (also known as metadata) facility to the Java Community Process in 2002; it gained approval in September 2004. Annotations became available in the language itself beginning with version 1.5 of the Java Development Kit (JDK).
A few examples of where types are used are class instance creation expressions (new), casts, implements clauses, and throws clauses. This form of annotation is called a type annotation [...].
To serialize an object means to convert its state to a byte stream so that the byte stream can be reverted back into a copy of the object. A Java object is serializable if its class or any of its superclasses implements either the java. io.
Compilers are encouraged to validate that a method or field marked with a @Serial annotation is one of the defined serialization-related methods or fields declared in a meaningful context and issue a warning if that is not the case. It is a semantic error to apply this annotation to other fields or methods, including:
Java Annotation is a tag that represents the metadata i.e. attached with class, interface, methods or fields to indicate some additional information which can be used by java compiler and JVM.
Repeating Annotations: These are the annotations that can be applied to a single item more than once. For an annotation to be repeatable it must be annotated with the @Repeatable annotation, which is defined in the java.lang.annotation package. Its value field specifies the container type for the repeatable annotation.
The @interface element is used to declare an annotation. For example: Here, MyAnnotation is the custom annotation name. There are few points that should be remembered by the programmer. Method should return one of the following: primitive data types, String, Class, enum or array of these data types.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With