Java Annotations

Java Annotations

This tutorial describes how to define your own annotations and how to use Java reflection to analyse your code with it.

Table of Contents

1. Annotations in Java
2. Defining own annotations
3. Using your annotation via Java reflection
4. Exercise: Define and analyse your own annotation
5. Thank you
6. Questions and Discussion
7. Links and Literature

    7.1. Source Code
    7.2. General

1. Annotations in Java

Annotations provide data about a class that is not part of the programming logic itself. They have no direct effect on the code they annotate. Other components can use this information. For example the @Override annotation is used by the Java compiler to check if the annotated method really overrides a method of an interface or the extended class.

Annotations can be preserved at runtime (RetentionPolicy.RUNTIME) or are only available at development time (RetentionPolicy.SOURCE).

2. Defining own annotations

The Java programming language allows to define your custom annotations.

Annotations are defined via the @interface annotation before the class name. Via @Retention you define if the annotation should be retained at runtime or not. @Target let you define where this annotation can be used, e.g. the class, fields, methods, etc.

A typical annotation definition would look like the following.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface InstallerMethod {
}

You can also define that your annotation is a qualifier for the @Inject annotation.

@javax.inject.Qualifier
@Documented
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface Checker {

}

3. Using your annotation via Java reflection

To process your annotation you could write your own annotation processor. Typically you use Java reflection for this. Java reflection allows you to analyse a Java class and use the information contained in this class.
4. Exercise: Define and analyse your own annotation

Create a new Java project called com.vogella.annotations.

Create the following two classes. The first class defines an annotation and the second class uses this to mark certain methods.

package com.vogella.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(value = ElementType.METHOD)
@Retention(value = RetentionPolicy.RUNTIME)
public @interface CanRun {

}

package com.vogella.annotations;

import java.lang.reflect.Method;

public class AnnotationRunner {

  public void method1() {
    System.out.println("method1");
  }

  @CanRun
  public void method2() {
    System.out.println("method2");
  }

  @CanRun
  public void method3() {
    System.out.println("method3");
  }

  public void method4() {
    System.out.println("method4");
  }

  public void method5() {
    System.out.println("method5");
  }

}

Afterwards create the following test class. The main method of this class analyzes the annotations and calls the corresponding methods.

package com.vogella.annotations;

import java.lang.reflect.Method;

public class MyTest {

  public static void main(String[] args) {

    AnnotationRunner runner = new AnnotationRunner();
    Method[] methods = runner.getClass().getMethods();

    for (Method method : methods) {
      CanRun annos = method.getAnnotation(CanRun.class);
      if (annos != null) {
        try {
          method.invoke(runner);
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    }
  }
}

5. Thank you

Please help me to support this article: