Java Object Oriented Design - Java Annotation Usage








The supplied value for elements of an annotation must be a compile-time constant expression and we cannot use null as the value for any type of element in an annotation.

Primitive Types

The data type of an element in an annotation type could be any of the primitive data types: byte, short, int, long, float, double, boolean, and char.

The Version annotation type declares two elements, major and minor, and both are of int data type.

The following code declares an annotation type:

public @interface MyAnnotation {
  byte a();/*  www  .  jav  a2  s  .  c om*/

  short b();

  int c();

  long d();

  float e();

  double f();

  boolean g();

  char h();
}
@MyAnnotation(a=1, b=2,  c=3,  d=4,  e=12.34F, f=1.89, g=true, h='Y')

We can use a compile-time constant expression to specify the value for an element of an annotation.

The following two instances of the Version annotation are valid:

@Version(major=2+1, minor=(int)13.2)
@Version(major=3, minor=13)




String Types

We can use an element of the String type in an annotation type.

The following code defines an annotation type called Name. It has two elements, first and last, which are of the String type.

public @interface Name  { 
   String first(); //from w w w  . j  a  v  a 2  s . c o  m
   String last();
}

@Name(first="Tom", last="Smith")
public class NameTest {
    @Name(first="Jack", last="Iaan")
    public void  aMethod()   {
    }
}

It is valid to use the string concatenation operator + in the value expression for an element of a String type.

@Name(first="Ja" + "ck", last="Ia" + "an")




Class Types

The following code shows how to use Class type as the annotation value.

import java.io.IOException;
/*  www  .  j a v a 2  s. c om*/
@interface MyAnnotation {
  Class<? extends Throwable> willThrow() default java.lang.Throwable.class;
}

public class Main {
  @MyAnnotation(willThrow = IOException.class)
  public static void testCase1() {
    // Code goes here
  }

  @MyAnnotation()
  public static void testCase2() {
  }
}

Enum Type

An annotation can have elements of an enum type.

enum Level {/*ww w.  j av a  2 s. com*/
  PENDING, FAILED, PASSED;
}

@interface Review {
  Level status() default Level.PENDING;

  String comments() default "";
}

@Review(status = Level.PASSED)
public class Main {

}

Annotation Type

We can use an annotation type as the type of an element inside another annotation type's declaration.

To provide a value for an element of an annotation type, use the syntax that is used to create an annotation type instance.

@interface Name {
  String first();// w w  w.j  a  v  a2  s  . c  om

  String last();
}

@interface Version {
  int major();

  int minor() default 0; // zero as default value for minor
}

@interface Description {
  Name name();

  Version version();

  String comments() default "";
}

@Description(name = @Name(first = "Tom", last = "Smith"), version = @Version(major = 1, minor = 2), comments = "Just a  test class")
public class Main {

}

Array Type Annotation Element

An annotation can have elements of an array type. The array type could be of one of the following types:

  • A primitive type
  • java.lang.String type
  • java.lang.Class type
  • An enum type
  • An annotation type

We need to specify the value for an array element inside braces.

Elements of the array are separated by a comma.

@interface ItemList {
  String[] items();
}

@ItemList(items = { "A", "B" })
public class Main {
   
}

If you have only one element in the array, it is allowed to omit the braces.

@ToDo(items={"A"})
@ToDo(items="A")

To pass in an empty array

@ToDo(items={}) 

Shorthand Annotation Syntax

Suppose we have an annotation type as follows.

public  @interface Enabled  {
    boolean status() default true;
}

To annotate a program element with the Enabled annotation type with the default value, we can use the @Enabled() syntax.

We do not need to specify the values for the status element because it has a default value.

We can further omit the parentheses.

@Enabled
public class Main {

}

@Enabled()
public class Main {

}

An annotation type with only one element has a shorthand syntax.

If an annotation type has only one element with named value, we can omit the name from name=value pair.

The following code declares a Company annotation type, which has only one element named value:

public  @interface Company  {
    String value(); 
}

We can omit the name from name=value pair when using the Company annotation.

@Company(value="Inc.")
public class Test   {
}

becomes

@Company("Inc.")
public class Test   {
}

The following code shows how to use this shorthand if the element data type is an array.

public  @interface Item   {
    String[] value();
}

@Item({"A", "B"})
public class Test   {
}

We can further omit the braces if we specify only one element in the array annotation type.

@Item("A")
public class Test   {
}

If we supply only one value when using an annotation, the name of the element is assumed value.