Learnitweb

Custom annotation in Java

  • 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:

CLASSAnnotations are to be recorded in the class file by the compiler but need not be retained by the virtual machine at run time.
RUNTIMEAnnotations 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.
SOURCEAnnotations 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:

@DocumentedIndicates that annotations with a type are to be documented by javadoc and similar documentation tools by default.
@RetentionIndicates 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.
@TargetSpecifies 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).
@InheritedIndicates 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 { ... }