Get Annotations and Declared Annotations Example

0

An annotation is a kind of interface. We can have annotations directly present on a class or indirectly, if the annotation’s type is inheritable and is present on one of its super class. In this article, we will see how to read the direct and indirect inherited annotations reflectively.

Annotation APIs

Annotation APIs we will examine are:

  1. Class.getAnnotations() – Gets all the annotations present on the class, both direct and indirect.
  2. Class.getDeclaredAnnotations() – Gets all the annotations directly present on the class.

Annotation Example

Our example consists of Cat class that extends Mammal which in turn extends Animal. There are some annotations present on each class based on the characteristics.
annotaion_Example
Animal class contains annotation Annot_AnimalType to classify the animal based on whether it belongs to mammal, reptiles, birds etc.

Animal:

package com.javarticles.annotations;

@Annot_AnimalType
public class Animal {
}

The class to which the animal belongs is defined in an enum <AnimalType. By default the animal type is MAMMAL. We use @Inherited to indicate that an annotation type is automatically inherited.

Annot_AnimalType:

package com.javarticles.annotations;

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

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Inherited
public @interface Annot_AnimalType {
    AnimalType value() default AnimalType.MAMMAL;
}

AnimalType:

package com.javarticles.annotations;

public enum AnimalType {
    MAMMAL,
    REPTILES,
    BIRDS,
    INSECTS,
    SPIDERS,
    AQUATIC
}

Let’s have another Class Mammal which extends Animal. We will add couple of annotations to add some character to the Mammal group. Mammals are warm blooded and produce milk.

Mammal:

package com.javarticles.annotations;

@Annot_ProduceMilk
@Annot_Warmblooded
public class Mammal extends Animal {
}

Annot_ProduceMilk:

package com.javarticles.annotations;

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

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Inherited
public @interface Annot_ProduceMilk {
}

@Annot_Warmblooded:

package com.javarticles.annotations;

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

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Inherited
public @interface Annot_Warmblooded {
}

We will also use an interface IKitten and add annotation @Annot_Playful to it.

IKitten:

package com.javarticles.annotations;

@Annot_Playful
public interface IKitten {
}

Annot_Playful:

package com.javarticles.annotations;

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

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Inherited
public @interface Annot_Playful {
}

Finally here is the Cat class that extends Mammal and implements <codeIKitten. We further define cat’s color and its domestic nature using annotations.

Cat:

package com.javarticles.annotations;

@Annot_Color("Brown")
@Annot_Domestic
public class Cat extends Mammal implements IKitten {
}

Annot_Color:

package com.javarticles.annotations;

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

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Annot_Color {
    String value()  default "white";
}

In our main class, we print Cat‘s annotations both direct and indirect. You can check whether an annotation is present using Class.isAnnotationPresent(). We also print whether the annotation is an inherited one. In order to find whether an annotation has @Inherited annotation, we need to get the annotation type Annotation.annotationType() and then call getDeclaredAnnotations() to find out the direct annotations present on the class. If the annotation has an annotation of type name "java.lang.annotation.Inherited" then it means the annotation type is Inherited.

Annotation[] declAnnotations = annotationClass.getDeclaredAnnotations();
        for (Annotation decAnnotation : declAnnotations) {
            if ("java.lang.annotation.Inherited".equals(decAnnotation.annotationType().getName())) {
                return true;
            }
        }

AnnotationExample:

package com.javarticles.annotations;

import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;

public class AnnotationExample {
    public static void main(String[] args) {
        AnnotatedElement annotatedElement = Cat.class;
        System.out.println("Cat.class.getAnnotations():");
        System.out.println("_________________________________________");
        Annotation[] annotations = annotatedElement.getAnnotations();
        printAnnotations(annotations);
        
        System.out.println("\nCat.class.getDeclaredAnnotations():");
        System.out.println("__________________________________________");
        Annotation[] declaredAnnotations = annotatedElement
                .getDeclaredAnnotations();
        printAnnotations(declaredAnnotations);
        System.out.println("\nCat.class.getAnnotation(annotationClass)");
        System.out.println("__________________________________________");
        printAnnotation(Cat.class,Annot_Color.class);
        printAnnotation(Cat.class, Annot_Domestic.class);
        printAnnotation(Cat.class, Annot_AnimalType.class);
        printAnnotation(Cat.class, Annot_Playful.class);        
        printAnnotation(Cat.class, Annot_ProduceMilk.class);
        printAnnotation(Cat.class, Annot_Warmblooded.class);
        
        System.out.println("\nCat.class.isAnnotationPresent(Annot_Warmblooded.class)");
        System.out.println("_________________________________________________________");
        System.out.println(Cat.class.isAnnotationPresent(Annot_Warmblooded.class));
    }

    private static void printAnnotations(Annotation[] annotations) {
        for (Annotation annotation : annotations) {
            System.out.println(annotation.annotationType().getTypeName() + 
                    (isAnInheritedAnnotation(annotation) ? "(Inherited)" : ""));
        }
    }

    private static <A extends Annotation> void printAnnotation(Class<?> clazz, Class<A> annotationClass) {
        Annotation annotation = clazz.getAnnotation(annotationClass);
        if (annotation != null) {
            System.out.println(annotation.annotationType().getTypeName() + 
                    (isAnInheritedAnnotation(annotation) ? "(Inherited)" : ""));
        } else {
            System.out.println(annotationClass.getSimpleName() + " not found on class " + clazz.getSimpleName());
        }
    }
    
    private static <A extends Annotation> boolean isAnInheritedAnnotation(A annotation) {
        Class<? extends Annotation> annotationClass = annotation.annotationType();
        Annotation[] declAnnotations = annotationClass.getDeclaredAnnotations();
        for (Annotation decAnnotation : declAnnotations) {
            if ("java.lang.annotation.Inherited".equals(decAnnotation.annotationType().getName())) {
                return true;
            }
        }
        return false;
    }
}

Output:

Cat.class.getAnnotations():
_________________________________________
com.javarticles.annotations.Annot_AnimalType(Inherited)
com.javarticles.annotations.Annot_ProduceMilk(Inherited)
com.javarticles.annotations.Annot_Warmblooded(Inherited)
com.javarticles.annotations.Annot_Color
com.javarticles.annotations.Annot_Domestic(Inherited)

Cat.class.getDeclaredAnnotations():
__________________________________________
com.javarticles.annotations.Annot_Color
com.javarticles.annotations.Annot_Domestic(Inherited)

Cat.class.getAnnotation(annotationClass)
__________________________________________
com.javarticles.annotations.Annot_Color
com.javarticles.annotations.Annot_Domestic(Inherited)
com.javarticles.annotations.Annot_AnimalType(Inherited)
Annot_Playful not found on class Cat
com.javarticles.annotations.Annot_ProduceMilk(Inherited)
com.javarticles.annotations.Annot_Warmblooded(Inherited)

Cat.class.isAnnotationPresent(Annot_Warmblooded.class)
_________________________________________________________
true

Download the source code

This was an example about getting declared annotations and the annotations which included the inherited ones from the super classes.

You can download the source code here: javaGetAnnotationsExample.zip
Share.

Comments are closed.