CHAPTER 23

Annotations

What are annotations? From Java 5 onwards there is a new reference data type added in the Java language, which allows us to annotate any programming element. Annotations are used like modifiers, which are created by the developer. We can create annotations which can be used with any kind of target type (programming element) within the Java source file. These are kinds of additional modifiers which a developer creates, normally to be used by some other kinds of processing tools (known as Annotation Processing Tools). javadoc is an example of a similar tool. It works on the Java source file. It processes the source file and generates the documentation. While processing the Java source file the javadoc utility uses the documentation comments found before any of the elements of the source code, which are normally the class or interface definition, the constructor, the methods, the instance and the class variables, and the member classes and interfaces. Only thing here is that in case of javadoc the documentation comments, which will be processed by the utility, are the ones which appear just before the modifiers for the element for which the documentation comment is defined, whereas in case of annotation processing tools, the annotated elements within the source file will be used by them. Annotations are equivalent to the modifiers and can be mixed with modifiers. Conventionally, annotations are normally used before all other modifiers, and the rest of the modifiers start from a new line. Another important difference is that the annotations can have attributes for which values can be specified at the time of usage. Some of these attributes can have default values. Let us look at how to define annotations and then how we use them to annotate various programming elements in a Java source file.

23.1 DEFINING A NEW ANNOTATION

An annotation is defined by using the keyword interface prefixed with @ character as shown below:

    1     public @interface NewAnnotation { // this defines an annotation
           called NewAnnotation
 2
 3     }

An annotation can have attributes. When we define an annotation, we need to declare what attributes are permissible for the annotation. These lists of attributes for the annotation are defined using the elements of the annotation. The elements of an annotation are of a type and have a name. These elements of an annotation type are declared similar to the methods in an interface. These annotation types are not interfaces, they only use the syntax like an interface. The elements of an annotation can be of the following types only:

primitive types

String

enum

Another annotation

Class

array of any of the preceding types

The element is declared using the abstract method declaration as is done in an interface. So if we want to have an element called attrib1 of type String in the annotation NewAnnotation, it would be defined as follows:

    1     public @interface NewAnnotation { // this defines an annotation
            called NewAnnotation
 2        String attrib1();   // declare an element name attrib1
              of type String
 3     }

The elements of any annotation can have a default value, which can be specified in the declaration by using the keyword default, as shown in the following listing:

    1     public @interface NewAnnotation { // this defines an annotation
            called NewAnnotation
 2         String attrib1() default "value1"; // default for the
              attribute attrib1 will be value1
 3     }

The methods used for declaring the elements of an annotation type cannot have any parameters nor can they have any kind of throws clause. These cannot be of generic type, i.e. they cannot use the generic type variable. Also while defining an annotation, the annotation type cannot declare any extends clause to extend from any interface; they implicitly extend from the annotation interface from the java.lang.annotation package.

23.2 ANNOTATING A PROGRAMMING ELEMENT

Any of the programming elements where a modifier is allowed can be annotated. The following are the valid programming elements which may be annotated:

  • package
  • classes, interfaces, enums
  • annotations
  • static and non-static methods
  • constructors
  • instance and class variables
  • parameter variable declarations
  • local variable declarations

To annotate any element, we use any of the annotation types which have been defined using @interface along with the modifiers and specify the values for all its elements. Elements which do not have default values have to be compulsorily specified and initialized. While annotating an element the annotation name is preceded by the @ character and the attribute values are specified in parentheses as shown below:

    1     @NewAnnotation(attrib1="some value") // annotating the
          TestAnnotation class
 2     public class TestAnnotation {
 3         // some valid code
 4     }
23.3 ANNOTATION ELEMENT NAMES AND USAGE

When annotating any programming element (using an annotation), if the name of the element of the annotation being used is value, then it is not compulsory to use the element name along with the value of the element. We can simply use the value without using the name, e.g. if the element name of the element in the NewAnnotation, was value instead of the attrib1, as is currently then, while annotating any element with NewAnnotation, we need not explicitly specify the element name, as shown in the following listing:

    1     @NewAnnotation("some value") // annotating the TestAnnotation class
 2     public class TestAnnotation {
 3       // some valid code
 4     }

When the element type is an array, then it should be initialized using the array initializer, and in case the array has a single element then the braces around the array initializer may be discarded, e.g. if we have an element called updatedBy of type String[], to specify the developers who update the specified element, in our annotation NewAnnotation, then, it could be used as follows:

    1     @NewAnnotation("some value", updatedBy="author1")
 2     public class TestAnnotation {
 3       // some valid code
 4     }

for single value in updatedBy array, and

    1     @NewAnnotation("some value", updatedBy={"author1", "author2",
                      "author3"})
 2     public class TestAnnotation {
 3       // some valid code
 4     }

for multiple elements of the updatedBy element.

23.4 META-ANNOTATIONS

There are annotations which can be used to annotate an annotation. These can be applied to an annotation to restrict the target (where a particular annotation can be applied), or whether the annotation needs to be retained beyond the Java source code. The annotations which can be applied on an annotation are known as meta-annotations. There are two meta-annotations which are commonly known and used.

23.4.1 Restricting Applicability of an Annotation

The meta-annotation Target (defined in the java.lang.annotation) is used to restrict the application of the annotation to certain types of programming elements only. The Target meta-annotation has only one element which is an array of enum type java.lang.annotation.ElementType. The enum values for the ElementType are as follows:

 

ANNOTATION_TYPE Annotation type declaration
CONSTRUCTOR Constructor declaration
FIELD Field declaration (includes enum constants)
LOCAL_VARIABLE Local variable declaration
METHOD Method declaration
PACKAGE Package declaration
PARAMETER Parameter declaration
TYPE Class, interface (including annotation type), or enum declaration

So, if we want to restrict the usage of annotation NewAnnotation to only methods and constructors, then the NewAnnotation may be annotated using the meta-annotation Target as shown in the listing below:

import java.lang.annotation.*;

@Target({ElementType.METHOD, ElementType.CONSTRUCTOR}) // restricting

   the target elements

public @interface NewAnnotation { // this defines an annotation called

   NewAnnotation

       String attrib1() default "value1"; // default for the attribute

          attrib1 will be value1

}

23.4.2 Retention Policy

The annotations which are used in the specific source code are by default retained in the class files, whenever these are compiled. We can control the retention of a specific annotation usage by using the meta-annotation called @Retention. There are three enum values of the enum type RetentionPolicy, which can be used as the values of the Retention meta-annotation. The values are SOURCE, CLASS and RUNTIME. The annotations which have been annotated with a retention value of SOURCE are not retained beyond the source code, whereas the annotations which have been annotated with a retention value of CLASS are retained in the class files. These annotations are only recorded in the class files, but may not be available at runtime, where the class is loaded by the VM. The annotations which are annotated with the meta-annotation Retention with a value of RUNTIME are retained in the class files and are available at runtime. These annotations can be accessed reflectively by a Java application.

LESSONS LEARNED
  • Annotations are used to annotate various programming elements in the source file. These can then be used by various tools in different manners. Some of these could even be used by compilers, or other tools which are a part of JDK.
  • We can annotate an element by using it similar to a modifier for an element. By convention the annotation precedes all other modifiers for the element being annotated.
  • Annotations are defined similar to defining an interface. Here the keyword interface is preceded by the @ symbol.
  • Annotations can have attributes; these attributes are more commonly of type String. These attributes are defined by using method declarations with no parameters, method name being the attribute name desired, and the method return type is the type of the attribute. The type for an attribute can be any primitive type, String, enum type, another annotation, Class or array of any of these.
  • Most commonly if we have annotation with one attribute, we use the attribute name as value. While annotating a programming element, a value is specified for each attribute, except in cases where the attribute may have a default value declared.
  • Meta-annotations are annotations which are used to annotate an annotation. There are a few meta-annotations which are part of the Java API. The meta-annotation Target could be used to specify the target element types which can be annotated with the annotation being defined. The meta-annotation Retention can be used to specify the retention policy for the annotation being defined. Depending on where the tool will operate, if the tool operates on the source file, the retention policy can be specified for annotation to be retained only in the source code and not available in the class file.
EXERCISES
  1. State which of the following are true or false:
    1. An interface created by extending an Annotation Type interface becomes an Annotation Type.
    2. The attribute for an annotation can be of type StrinbBuffer.
    3. An attribute can be of an array type.
    4. An annotation which has been annotated with @Target annotation having value ANNOTATION_TYPE is a meta-annotation.
  2. Fill in the blanks in the following:
    1. All annotation types extend the __________ interface.
    2. The default attribute name for an attribute of an annotation with a single attribute is __________.
    3. The __________ meta-annotation can be used to specify the retention policy for the annotation.
    4. The __________ meta-annotation is used to specify the elements on which the annotation can be applied.
  3. Consider the following annotation definition:

        1 @interface MyAnnotation{
     2
     3 }

    Then let’s say in an application we obtain the Class instance for this annotation by using:

        1 Class c = Class.forName("MyAnnotation");

    Then which of the following method invocations on Class c will return true?

    1. c.isAnnotation()
    2. c.isPrimitive()
    3. c.isInterface()
    4. c.isArray()
  4. What are annotations, and how are they useful?
  5. List the various meta-annotations available in the Java API.
  6. List the various values for the @Target meta-annotation.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.116.21.152