Showing posts with label annotation. Show all posts

Understanding Annotations in Java

Annotation + Java

What is Annotations?
Annotations, a form of metadata, provide data about a program that is not part of the program it self. Annotations has no direct effect on the operation of the code they annotate.

Annotation Syntax
public @interface AnnotationName {
    String elementName();
 
    /* Element with default value */
    String elementDefault() default "HelloWorld";
}

Annotations used in example
We've used @Retention, @Target and @Documented annotations to understand basics of Annotations.

@Retention
Indicates how long annotations with the annotated type are to be retained.
  • RetentionPolicy.SOURCE – The marked annotation is retained only in the source level and is ignored by the compiler.
  • RetentionPolicy.CLASS – The marked annotation is retained by the compiler at compile time, but is ignored by the Java Virtual Machine (JVM).
  • RetentionPolicy.RUNTIME – The marked annotation is retained by the JVM so it can be used by the runtime environment.

@Target
Indicates the contexts in which an annotation type is applicable.
  • ElementType.ANNOTATION_TYPE can be applied to an annotation type.
  • ElementType.CONSTRUCTOR can be applied to a constructor.
  • ElementType.FIELD can be applied to a field or property.
  • ElementType.LOCAL_VARIABLE can be applied to a local variable.
  • ElementType.METHOD can be applied to a method-level annotation.
  • ElementType.PACKAGE can be applied to a package declaration.
  • ElementType.PARAMETER can be applied to the parameters of a method.
  • ElementType.TYPE can be applied to any element of a class.

@Documented
Indicates that annotations with a type are to be documented by javadoc and similar tools by default.

Source code (Default.java)
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Annotation to hold default value of field and method.
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD})
public @interface Default {
    String value();
}

Source code (Author.java)
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Annotation to hold the Author details.
 */
@Documented
/* Un-comment following two annotation in order to access it at Runtime in 'main' method of AnnotationExample.java */
// @Retention(RetentionPolicy.RUNTIME)
// @Target({ElementType.FIELD, ElementType.METHOD})
public @interface Author {
    /* 'company' element is optional because we provided default constant value. */
    String company() default "javaQuery";
    
    /* Compulsory elements of Author Annotation */
    String name();
    String date();
    String description();
}

Source code
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * Example of How to access annotations in Java
 * @author javaQuery
 * @date 13th October, 2015
 */
public class AnnotationExample {

    /* Variable/field with @Default annotation */
    @Default(value = "vicky.thakor@javaquery.com")
    private String email;

    /* Method with two @Author and @Default Annotation */
    @Author(name = "Vicky Thakor", date = "13th October, 2015", description = "Method prints welcome message")
    @Default("Hello World!")
    public String welcomeMessage() {
        return "Hello JavaQuery";
    }

    public static void main(String[] args) {
        System.out.println("Inspect class fields");
        System.out.println("++++++++++++++++++++++++++++++++++++++++");
        
        /* Get all declared fields of class */
        Field[] fields = AnnotationExample.class.getDeclaredFields();
        for (Field field : fields) {
            /* Check particular annotation is present or not */
            if (field.isAnnotationPresent(Default.class)) {
                Default getDefault = field.getAnnotation(Default.class);
                /* Get value of annotation */
                System.out.println("> Default value on field '" + field.getName() + "': " + getDefault.value());
            }
        }

        System.out.println("\n");
        System.out.println("Inspect class methods");
        System.out.println("++++++++++++++++++++++++++++++++++++++++");
        Method[] methods = AnnotationExample.class.getDeclaredMethods();
        for (Method method : methods) {
            /* Check particular annotation is present or not */
            /* In order to work following if uncomment @Retention and @Target in Author.java */
            if (method.isAnnotationPresent(Author.class)) {
                Author getAuthor = method.getAnnotation(Author.class);
                /* Get value of annotation */
                System.out.println("> Author name on method '" + method.getName() + "': " + getAuthor.name());
            } else {
                System.out.println("> Author annotation is not available on method '" + method.getName()+"'");
            }

            /* Check particular annotation is present or not */
            if (method.isAnnotationPresent(Default.class)) {
                Default getDefault = method.getAnnotation(Default.class);
                /* Get value of annotation */
                System.out.println("> Default value on method '" + method.getName() + "': " + getDefault.value());
            }
            System.out.println("--------------------------------------");
        }
    }
}

Output
Inspect class fields
++++++++++++++++++++++++++++++++++++++++
> Default value on field 'email': vicky.thakor@javaquery.com


Inspect class methods
++++++++++++++++++++++++++++++++++++++++
> Author annotation is not available on method 'main'
--------------------------------------
> Author annotation is not available on method 'welcomeMessage'
> Default value on method 'welcomeMessage': Hello World!
--------------------------------------