25.4 Meta-Annotations

Meta-annotations are annotations that can be applied on an annotation type declaration to specify various aspects of the annotation when this annotation type is applied in the source code. We discuss the purpose and usage of predefined meta-annotations when declaring an annotation type, as they have implications on how the annotation will be handled when applied in the source code.

@Retention: Specifies how this annotation is retained when applied, whether in the source file, in the class file, or at runtime.

@Target: Specifies to which contexts in the source code this annotation can be applied.

@Inherited: Indicates that all subclasses of a superclass that this annotation is applied to will inherit this annotation.

@Repeatable: Indicates that this annotation can be used multiple times in the same context.

@Documented: Indicates that this annotation should be included in the documentation generated by a tool like javadoc.

The @Retention Meta-Annotation

In the declaration of an annotation type, it is possible to specify how long the annotation will be retained, meaning whether it should be in the source file, in the class file, or available at runtime.

In fact, each annotation is associated with one of three retention policies, controlled by the meta-annotation type java.lang.annotation.Retention and the retention policy constants defined by the enum type java.lang.annotation.RetentionPolicy shown in Table 25.1 in increasing order of retention.

The meta-annotation type Retention is a single-element meta-annotation type that specifies a value() element of enum type RetentionPolicy. Defining value() elements is covered elsewhere in this chapter (p. 1560).

Click here to view code image

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(value = RetentionPolicy.RUNTIME)   // Retention: In source code,
                                              // in class file, at runtime.
public @interface MusicMeta {}

The annotation type MusicMeta above needs to be retained at runtime so that it is possible to extract any information that is specified by this annotation. The Retention-Policy.RUNTIME enum constant provides the longest retention. If used in the source code, the @MusicMeta annotation will be recorded in the class file, and when loaded at runtime, it will be available through reflection. However, no provision has been made as yet in the MusicMeta annotation type declaration to provide any information. It is added to the annotation type declaration by specifying annotation type elements (p. 1560).

Click here to view code image

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(value = RetentionPolicy.SOURCE) // Retention: Only in the source code.
public @interface Override {}

The code above shows the declaration of the Override annotation type. This builtin annotation type when applied in the source code can be used by the compiler (p. 1578). Its declaration specifies the RetentionPolicy.SOURCE, meaning that the annotation will only be retained in the source code. In other words, it will not be recorded in the class file or be available at runtime.

The annotation type declarations shown above do not contain any annotation type elements. They are marker annotation types. The purpose of a marker annotation type is to indicate the presence of a feature, rather than convey any specific information. As the MusicMeta annotation type declaration stands, it is possible to discover at runtime that this annotation is used on a particular program element and take the appropriate action, whatever that might be. Use of the @Override marker annotation in the source code alerts the compiler to check that the criteria for overriding is satisfied by the method on which this annotation is applied, but the annotation is not recorded in the class file.

Table 25.1 Retention Policy Values for the @Retention Meta-Annotation

Constants defined by the RetentionPolicy enum typeDescription
SOURCEThis retention policy implies that the annotation is only retained in the source code and is discarded by the compiler—that is, it is not recorded in the class file. The purpose of this annotation is to provide information for the compiler—for example, to validate source code, detect design errors, and suppress compiler warnings.
CLASSThis retention policy implies that the annotation is recorded in the class file and thus retained by the compiler, but it is not intended to be used at runtime. That it, it need not be loaded by the JVM at runtime. The purpose of this annotation is to provide information for compile-time and deployment-time processing. It can be used by tools that process information to generate additional code—for example, deployment descriptors such as XML files used by Java EE/Jakarta. RetentionPolicy.CLASS is the default retention policy if no retention policy is specified on the annotation type declaration.
RUNTIMEThis retention policy results in the annotation being recorded in the class file by the compiler. It is retained by the JVM and can be read at runtime via reflection.

Leave a Reply

Your email address will not be published. Required fields are marked *