In the previous posts we learn the use of @Target and @Retention annotation. Now we understand this with the help of an example illustrated here.

The program presented here uses the introspection and reflection feature of the Java language. Let’s briefly discuss this feature so that we will not have any difficulties in understanding how annotations are discovered at runtime.

·   When the JVM loads a class in memory, it creates an object of the Class type for the loaded class. This object contains all the details about the class, which are available in its source program.

·   We obtain a reference to this Class object by calling the getClass method on an object loaded in memory.

·     We can introspect the various methods of the loaded class by calling the getMethods method on the Class object. The method returns an array of Method objects.

·    Method is a class that defines the physical representation of a method of a class. For example,

1- the getName method of the Method class returns its name;

2- the getParameterTypes method returns an array of Class objects that represent the formal parameter types;

3- the getReturnType method returns a Class object that represents the formal return type of the method.

In the program that follows, we use the getAnnotation method to obtain the annotation, if any, associated with the method. With this little introduction to introspection and reflection, we are now ready to learn the runtime discovery of annotations. You are encouraged to refer to the javadocs API for a full treatment of introspection and reflection.

Program Code
import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;

public class RuntimeAnnotation {
                     @Task(description = "Implement tax computations", estimatedHours = 50,                                          additionalNote = "This implementation is critical for the final launch")
                     public static float ComputeTax(float amount, float rate) {
                             return 0;
                     public static void main(String args[]) {
                             try {
                                      RuntimeAnnotation obj = new RuntimeAnnotation();
                                      Class cls = obj.getClass();
                                      WorkInProgress annotation = (WorkInProgress) cls
                                                          .getAnnotation(WorkInProgress.class);                                       System.out.println("Class " + cls.getName());
                                      if (cls.isAnnotationPresent(WorkInProgress.class)) {                                            System.out.println("\tThis class is not fully mplemented");                                       }
                                      System.out.println("\nList of methods:");                                       Method[] methods = cls.getMethods();
                                    for (Method method : methods) {
                                                System.out.println(method.getName());                                          if (method.isAnnotationPresent(WorkInProgress.class) {                                             System.out.println("\tThis method is not fully implemented");                                                 }
                                                if (method.isAnnotationPresent(Task.class)) {                                                           Task annotationTask = (Task) method                                                                              .getAnnotation(Task.class);                                                           System.out.printf("\tWhat TODO: "                                                           + annotationTask.description()                                                               + "%n\tTarget date: " +                                                                                     annotationTask.targetDate()                                                           + "%n\tEstimated hours: " +annotationTask.estimatedHours()
                                                                                + "%n\tNote: "
                                                          + annotationTask.additionalNote() + "%n");
                             } catch (Exception e) {
@interface WorkInProgress {
@interface Task {
                     String description();
                     String targetDate() default "May 22, 2016";
                     int estimatedHours();
                     String additionalNote();



Like in earlier cases, we declare two annotations—WorkInProgress and Task—both having the same definitions as in the earlier examples. However, we apply a retention policy on both with the following statement:


Thus, these annotations are now available at runtime, which is what we want for this demonstration.

The main application class is RuntimeAnnotation. We apply the WorkInProgress annotation to it by preceding the class declaration with the @WorkInProgress annotation.

In the class definition, first we define the method ComputeTax, to which we apply the two annotations—WorkInProgress and Task. Next, we define the main method. We do not apply any annotations to it because we have fully implemented this method. In the main method, we create an instance of RuntimeAnnotation. Now comes the important part of introspection and displaying the annotation information at runtime. To do this, the program obtains the type of the created object by calling its getClass method:

Class cls = obj.getClass();

The program now obtains the associated annotation by calling the getAnnotation method on the obtained Class object:

WorkInProgress annotation = (WorkInProgress) cls.getAnnotation(WorkInProgress.class);

The getAnnotation method takes one parameter that specifies the annotation class type. Therefore, the method retrieves the annotation of the specified type, and if it is not found, null is returned. The program now retrieves the class name by calling its getName method for display to the user:

System.out.println("Class " + cls.getName());

Next, we check whether this element (the class) has an annotation present by calling the isAnnotationPresent method on the Class object; if it does, we print an appropriate message to the user:

if (cls.isAnnotationPresent(WorkInProgress.class)) {

System.out.println("\tThis class is not fully implemented");


We now introspect the class object cls to discover all the methods defined in it. This is done by calling the getMethods method on the Class object:

Method[] methods = cls.getMethods();

The method returns an array of Method objects. A Method is a class defined in the java.lang. reflect package and represents a method declaration in a class.

The method returns us the array of all the methods defined for the class. We iterate through this list by using a foreach loop:

for (Method method : methods) {

For each method, we print its name:


For each method, we check whether WorkInProgress annotation has been applied to it:

if (method.isAnnotationPresent(WorkInProgress.class)) {

System.out.println("\tThis method is not fully implemented");

Next, we check whether the Task annotation has been applied:

if (method.isAnnotationPresent(Task.class)) {

If so, we get the various members of the Task annotation and print their values to the console:

Task annotationTask = (Task) method.getAnnotation(Task.class);
System.out.printf("\tWhat TODO: "
+ annotationTask.description()
+ "%n\tTarget date: " + annotationTask.targetDate()
+ "%n\tEstimated hours: "
+ annotationTask.estimatedHours()
+ "%n\tNote: " + annotationTask.additionalNote()
+ "%n");


When we run the application, we see the following output:

Class RuntimeAnnotation

               This class is not fully implemented
List of methods:
               This method is not fully implemented
                What TODO: Implement tax computations
                Target date: May 20, 2016
                Estimated hours: 50
                Note: This implementation is critical for the final launch
wait wait


In the output, observe how the messages for the two annotations are printed and how the values of different members of the Task annotation are printed to the console.

  Modified On Dec-18-2017 04:20:00 AM

Leave Comment