Intro To Java Annotations
Intro To Java Annotations
By M. M. Islam Chisty
October 14, 2005
The objective of changing older JDK versions to JDK5 largely centered on enhancing
ease-of-development. In other words, the new features shift the responsibility for writing the
boilerplate code from the programmer to the compiler. If the source code is boilerplate free, it
becomes easier to maintain. The resulting codes are also less likely to be bug-prone. One of these
new ease-of-development features in JDK5 are annotations. Annotations are like meta-tags that you
can add to your code and apply them to package declarations, type declarations, constructors,
methods, fields, parameters, and variables. As a result, you will have helpful ways to indicate
whether your methods are dependent on other methods, whether they are incomplete, whether
your classes have references to other classes, and so on.
The Basics
There are two things you need to consider with annotations. One is the "annotation" itself; another
is the "annotation type." An annotation is the meta-tag that you will use in your code to give it some
life. Annotation type is used for defining an annotation. You will use it when you want to create your
own custom annotation. The type is the actual construct used, and the annotation is the specific
usage of that type.
An annotation type definition takes an "at" (@) sign, followed by the interface keyword plus the
annotation name. On the other hand, an annotation takes the form of an "at" sign (@), followed by
the annotation type. This is simplest form of annotation. Additionally, you can put data within
parenthesis after the annotation name. An example of each can be seen below:
Annotation Types
There are three annotation types:
Marker: Marker type annotations have no elements, except the annotation name itself.
Example:
Usage:
@MyAnnotation
public void mymethod() {
....
}
Example:
Usage:
Example:
Usage:
1. Annotation declaration should start with an 'at' sign like @, following with an interface
keyword, following with the annotation name.
2. Method declarations should not have any parameters.
3. Method declarations should not have any throws clauses.
4. Return types of the method should be one of the following:
primitives
String
Class
enum
array of the above types
Annotations
There are two types of annotations available with JDK5:
Simple annotations: These are the basic types supplied with Tiger, which you can use to
annotate your code only; you cannot use those to create a custom annotation type.
Meta annotations: These are the annotation types designed for annotating annotation-type
declarations. Simply speaking, these are called the annotations-of-annotations.
Simple Annotations
There are only three types of simple annotations provided by JDK5. They are:
Override
Deprecated
Suppresswarnings
It's important to note that JDK5 (in other words, Tiger) actually does not have many built-in
annotations; rather, it allows core Java the ability to support the annotation feature. The charter for
JSR-175 strictly dictated it was to define a metadata facility. It was left to the programmers to write
custom annotation types and to other JSRs to write a set of standard annotation types. The
following sections will describe each simple annotation in more depth, along with examples.
An override annotation indicates that the annotated method is required to override a method in a
super class. If a method with this annotation does not override its super-class's method, the
compiler will generate an error. Example 1 demonstrates the override annotation:
Example 1
What happens if a spelling mistake occurs with the method name? For example, if you change the
name of the toString method to "tostring" and compile the code, you will get something like the
following:
This annotation indicates that when a deprecated program element is used, the compiler should
warn you about it. Example 2 shows you the deprecated annotation.
Example 2
The doSomething() method in this example is declared as a deprecated method. Therefore, this
method should not be used when this class is instantiated by other classes. If you compile
Test_Deprecated.java, no warning messages will be generated by the compiler. But, if you try to
compile TestAnnotations.java where the deprecated method is used, you will see something like
this:
This annotation indicates that compiler warnings should be shielded in the annotated element and all
of its sub-elements. The set of warnings suppressed in an element is the superset of the warnings in
all of its containing sub-elements. As an example, if you annotate a class to suppress one warning
and one of its methods to suppress another warning, both warnings will be suppressed at the
method level only. See Example 3 for the suppresswarnings annotation.
Example 3
Note: It is a good idea to use this annotation at the most deeply nested element where
it is effective. Therefore, if you want to suppress a warning in a particular method, you
should annotate that method rather than its class.
Target
Retention
Documented
Inherited
The target annotation indicates the targeted elements of a class in which the annotation type will be
applicable. It contains the following enumerated types as its value:
Example 4
@Target(ElementType.METHOD)
public @interface Test_Target {
public String doTestTarget();
}
The @Target(ElementType.METHOD) indicates that this annotation type can be used to annotate
only at the method levels. If you compile the preceding code, no warning messages will be shown.
Now, if you declare a String variable and apply your newly created annotation, what will happen?
Let me demonstrate this as follows:
The only change you can see from above is that the annotation declaration is shifted from
method-level to field-level, which is not correct. Because you have defined your annotation
@Test_Target to be applicable only at method-level, if you try to compile this class, you are likely to
get something like this:
"TestAnnotations.java":
D:R_AND_DTestAnnotationsrctestmyannotation
TestAnnotations.java:16:
annotation type not applicable to this kind of declaration at line
16, column 0
@Test_Target(doTestTarget="Hello World !")
^
Error in javac compilation
The Retention annotation
The retention annotation indicates where and how long annotations with this type are to be retained.
There are three values:
RetentionPolicy.SOURCE—Annotations with this type will be by retained only at the source level
and will be ignored by the compiler
RetentionPolicy.CLASS—Annotations with this type will be by retained by the compiler at
compile time, but will be ignored by the VM
RetentionPolicy.RUNTIME—Annotations with this type will be retained by the VM so they can be
read only at run-time
Example 5
@Retention(RetentionPolicy.RUNTIME)
public @interface Test_Retention {
String doTestRetention();
}
The documented annotation indicates that an annotation with this type should be documented by the
javadoc tool. By default, annotations are not included in javadoc. But if @Documented is used, it then
will be processed by javadoc-like tools and the annotation type information will also be included in the
generated document. Example 6 demonstrates using @Documented further:
Example 6
@Documented
public @interface Test_Documented {
String doTestDocument();
}
Now, if you run the javadoc command and view the generated TestAnnotations.html file, you will see
something like Figure 1.
Figure 1
As you can see from the screenshot, there is no annotation-type information for the
doSomeTestRetention() method. But, this description is provided for the doSomeTestDocumented()
method. This is because of the @Documented tag attached with your Test_Documented annotation.
Your earlier annotation Test_Retention did not include this tag.
This is a bit of a complex annotation type. It indicates that the annotated class with this type is
automatically inherited. More specifically, if you define an annotation with the @Inherited tag, then
annotate a class with your annotation, and finally extend the class in a subclass, all properties of the
parent class will be inherited into its subclass. With Example 7, you will get an idea about the benefits of
using the @Inherited tag.
Example 7
@Inherited
public @interface myParentObject {
boolean isInherited() default true;
String doSomething() default "Do what?";
}
@myParentObject
public Class myChildObject {
}
As you can see, you do not have to define the interface methods inside the implementing class. These
are automatically inherited because of using the @Inherited tag. What would happen if you define the
implementing class in old-fashioned Java-style? Take a look at this—defining the implementation class in
an old-style-java way:
Do you see the difference? You can see that you will have to implement all the methods that the parent
interface owns. Besides the isInherited() and doSomething() methods from myParentObject, you will
have to implement the equals(), toString(), and hasCode() methods of java.lang.Object and also the
annotationType() method of java.lang.annotation.Annotation class. It does not matter whether you want
to implement these methods or not; you will have to include these in your inherited object.
Conclusion
This article has shown you how you can make your development easier through the use of JDK5's
annotation feature. Annotations do not directly affect the semantics of a program. Development and
deployment tools can read these annotations and process them in some fashion, perhaps producing
additional Java programming language source files, XML documents, or other artifacts to be used in
conjunction with the program containing the annotations. You now can do the same things as you would
do before, but with less code and better compile-time error detection. The objective is to spend less
time on unhandy code-writing and focus more on business logic rules. This article is Part I of a series on
Java Annotations. In Part II, you will learn about how to use annotations to develop a simple Web
application with a flat table. Lastly, in Part III you will see a complex example that includes multiple
database tables relationships.
Resources
1. New Features and Enhancements J2SE 5.0 at
http://www.mathcs.carleton.edu/courses/course_resources/j2se-1.5.0-docs/relnotes/features.html
2. J2SE 5.0 in a Nutshell at http://java.sun.com/developer/technicalArticles/releases/j2se15/
3. Annotations in Tiger, Part 1: Add metadata to Java code at
http://www-128.ibm.com/developerworks/java/library/j-annotate1/
4. What's New in Java 1.5? at http://www.cs.indiana.edu/classes/jett/sstamm/
5. Tiger in NetBeans4 at
http://cropcrusher.web.infoseek.co.jp/shufujava/sunone/nb/nb4tiger_en.html
6. Taming the tiger at http://www.denverjug.org/meetings/files/200408_Tiger.pdf