- Declaration of an annotation is similar to interface declaration.
- An at-sign (@) precedes the
interface
keyword, then comes the annotation name. Then there are method declarations. Each method declaration defines an element of the annotation type. - Method declarations must not have any parameters or a throws clause.
- Return types are restricted to primitives, String, Class, enums, annotations, and arrays of the preceding types.
- Methods can have default values.
In the following example, we are creating an annotation TestAnnotationForClass
.
import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @Retention(RetentionPolicy.RUNTIME) @interface TestAnnotationForClass { String author(); String date(); int currentRevision() default 1; String lastModified() default "Not applicable"; String lastModifiedBy() default "Not applicable"; }
Now, we’ll use TestAnnotationForClass
annotation for Test
class.
@TestAnnotationForClass ( author = "Editorial Team", date = "9/18/2020", currentRevision = 6, lastModified = "9/18/2020", lastModifiedBy = "Editorial Team" ) public class Test { public static void main(String[] args) { Test t = new Test(); //print annotations of class Test System.out.println(t.getClass().getAnnotations()[0]); } }
In this example, we have used RetentionPolicy.RUNTIME
because we want to demonstrate and read annotation at runtime. RetentionPolicy.RUNTIME
indicates that annotations are to be recorded in the class file by the compiler and retained by the virtual machine at run time, so they may be read reflectively.
Output
@TestAnnotationForClass(currentRevision=6, lastModified=9/18/2020, lastModifiedBy=Editorial Team, author=Editorial Team, date=9/18/2020)
Rentention Policy
Retention policy specifies how long annotations are to be retained.
Following constants of enumerated type describe various retention policies:
CLASS | Annotations are to be recorded in the class file by the compiler but need not be retained by the virtual machine at run time. |
RUNTIME | Annotations are to be recorded in the class file by the compiler and retained by the virtual machine at run time, so they may be read reflectively. |
SOURCE | Annotations are to be discarded by the compiler. |
Meta-annotations
Meta-annotations are annotations that are applied to other annotations.
J2SE 5.0 provides four annotations in the java.lang.annotation package that are used only when writing annotations:
@Documented | Indicates that annotations with a type are to be documented by javadoc and similar documentation tools by default. |
@Retention | Indicates how long annotations with the annotated type are to be retained. If no Retention annotation is present on an annotation type declaration, the retention policy defaults to RetentionPolicy.CLASS. A Retention meta-annotation has effect only if the meta-annotated type is used directly for annotation. It has no effect if the meta-annotated type is used as a member type in another annotation type. |
@Target | Specifies the kinds of program element to which an annotation type is applicable. If a Target meta-annotation is not present on an annotation type declaration, the declared type may be used on any program element. ANNOTATION_TYPE, CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER and TYPE are valid values for element type (or you can say program elements). |
@Inherited | Indicates that an annotation type is automatically inherited. |
Marker annotation type
An annotation type with no elements is termed a marker annotation type, for example:
public @interface MarkerAnnotation { }
It is permissible to omit the parentheses in marker annotations, as shown below:
@MarkerAnnotation public class Test { ... }
Single element annotation
In annotations with a single element, the element should be named value, as shown below:
/** * Associates a greeting message with the annotated API element. */ public @interface Greeting { String value(); }
It is permissible to omit the element name and equals sign (=) in a single-element annotation whose element name is value, as shown below:
@Greeting("Hello World") public class Test { ... }