Monday, April 4, 2011

How to use java annotations

                            Annotations are some of the major introduction that came with JDK 5 . And now most of the developers are trend to use annotations. So I decide to write this article about annotations but this may not be suitable for experts who try to discover more with annotations because this article is most suitable for people who does not familiar with annotations.
Before we go further it is better to discuss some of the key factors of java annotations.
  • java annotations were introduced to the java world with JDK 5 (JSR 175)
  • Annotations are providing a strong mechanism to define meta data .
  • It improve readability of the code .
  • Can use in every where inside the code
  • Easy to define (no need of long set of configurations)
Basically there are three types of annotations
  1. Multi value annotations
  2. Single value annotations
  3. Marker annotations

It is easy to understand other two types of annotations if we define Multi value annotations so lets begin our new annotations as a multi value.
/**
 * @author amith jayasekara
 *         
 *         simple multi value annotation
 */
@interface MultivalueAnotaion {

    String message();
    //this will set mata data print number to 23 if there is
    // no explicitly deceleration

    int printNumber() default 23;

}
 

                          We define annotation with @interface . Then we can define over own methods inside the annotation class but keep in mind as interfaces annotation cannot have methods with body . So keep body of the method as empty .There are some restrictions while define method inside annotation.
  • Return type of method should be a primitive value or an Object type.
  • Or it can be a enum or other annotation type.
  • Or it can be array of above types .
  • No other return types are allows to use with annotation methods.
  • And there can not be generics in side annotations.
                         We can define default value for methods with default key word and they will be used if we does not define while using the annotation.

Improving above annotation .
              We can improve annotation with following two properties .
  • What extend the this annotation is retained .
  • Where we use this annotation.
Define what extend that this annotation will be retain.

                      To do that we can use another pre defined annotation called @Retention. There are 3 retaliation policies are defined with this annotation.
  • RetentionPolicy.RUNTIME
Retain annotation definition during the runtime (so java runtime can access meta data)
  • RetentionPolicy.CLASS(default type)
Retain annotation definition in the class file.
  • RetentionPolicy.SOURCE
Retain annotation definition in source file

Define where to use annotation.
                    To do that we can user another pre defined annotation called @Target . Follow are available options . Note that we can define more that one definition but it will give compiler error if we used same definition more that one inside the Element type array.
example :
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.FIELD})
this will give compile errors
check out available options for Element types here

So now we see the improved version of our multi valued annotation.

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

/**
 * @author amith jayasekara
 *        
 *         simple multi value annotation that retain in runtime and that
 *         can be used in class level
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
    @interface MultivalueAnotaion {

    String message();
    //this will set mata data print number to 23 if there is
    // no explicitly deceleration

    int printNumber() default 23;

}

                    Now we know how to define a simple annotation but it is no use if we don't know how to use this annotation . Follow is a sample code that define the usage of the annotation.

import java.lang.annotation.Annotation;

/**
 * @author amith jayasekara
 *         sample code for testing annotation in runtime of the programme
 */
@MultivalueAnotaion(message = "sample message")
public class MultivalueAnnotationTest {

    public static void main(String[] args) {
        //we create a object of the class
        MultivalueAnnotationTest test = new MultivalueAnnotationTest();

        //check is annotation is available
        if (test.getClass().isAnnotationPresent(MultivalueAnotaion.class)) {
            MultivalueAnotaion ma = test.getClass().getAnnotation(MultivalueAnotaion.class);
            System.out.println("annotation message " + ma.message());
            System.out.println("annotation print number " + ma.printNumber());
        }
    }
}

Single value annotation
 There is only method definition inside the annotation class.


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

/**
 * @author amith jayasekara
 *         single value annotation
 *         retain till runtime and only be able to apply for method level
 */

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
    @interface SingleValueAnnotation {
    boolean isPrintMessage() default true;
}

sample usage
import java.lang.reflect.Method;

/**
 * @author amith jayasekara
 */
public class SingleValueAnnotationTest {
    @SingleValueAnnotation
    public static void annotatedMethod() {
        SingleValueAnnotationTest st = new SingleValueAnnotationTest();
        Class cls = st.getClass();
        try {
            Method method = cls.getMethod("annotatedMethod");
            SingleValueAnnotation ano = method.getAnnotation(SingleValueAnnotation.class);
            System.out.println("is print message " + ano.isPrintMessage());
        } catch (NoSuchMethodException e) {
            System.out.println("no method found");
        }
    }

    public static void main(String[] args) {
        annotatedMethod();
    }
}



Marker annotation
                      If the annotation body does not contain any method that type of annotations are known as marker annotation . And their behavior is very much similar to marker interfaces.
Follow is a sample marker annotation and sample usage code for that annotation

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


/**
 * marker annotations
 * this annotation is available in runtime and  the target is class level
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
    @interface MyMarker {
}

sample usage class
/**
 * @author amith jayasekara
 */
public class MarkerAnoTest {
    public static void main(String[] args) {
        MarkerClass mark = new MarkerClass();
        if (mark.getClass().isAnnotationPresent(MyMarker.class)) {
            System.out.println("Mark is marked with marker annotation");
        }
    }
} 
 

There are many pre defined annotation are available with java if you are really interesting with what are they go through follow links .
devx.com