The first article in this series describes what metadata is, the importance of metadata, and how to use the basic built-in annotations of J2SE 5.0 (also known as Tiger). If you are accustomed to these concepts, you may already be thinking that the three standard annotations provided by Java 5 are not particularly robust, but only deprecated, suppresswarnings and Override are available. Fortunately, Tiger also allows you to define your own annotation types. In this article, I'll take a few examples to guide you through this relatively simple process. You'll also learn how to annotate your annotations and some of the benefits of doing so. I want to thank O ' Reilly Media, Inc., who have been very generous in allowing me to use the code example in the "Notes" chapter of my book on Tiger in this article.
To define your own annotation type
By adding a small syntax (Tiger adds a large number of syntax constructs), the Java language supports a new type-annotation type (annotation type). Annotation types look like ordinary classes, but have some unique properties. The most obvious point is that you can annotate other Java code in the class as a symbol (@). I will introduce this process step-by-step.
@interface statement
Defining a new annotation type has many similarities to creating an interface, except that there is a @ symbol before the interface keyword. An example of the simplest annotation type is given in Listing 1:
Listing 1. A very simple annotation type
package com.oreilly.tiger.ch06;
/**
* Marker annotation to indicate that a method or class
* is still in progress.
*/
public @interface InProgress { }
The meaning of Listing 1 is very clear. If you compile this annotation type and are sure it is in the classpath, you can use it in your source code method to indicate that a method or class is still being processed, as shown in Listing 2:
Listing 2. Use a custom annotation type
@com.oreilly.tiger.ch06.InProgress
public void calculateInterest(float amount, float rate) {
// Need to finish this method later
}
The annotation type shown in Listing 1 is used in exactly the same way as the built-in annotation type, except that the name and package are used to indicate custom annotations. Of course, the general Java rules still apply, you can import the annotation type, use @InProgress to reference it directly.
Add members
The basic usage shown above is far from robust enough. You must remember that the annotation type can have member variables, as mentioned in part 1th. This is useful, especially when you are ready to use annotations as more complex metadata, not just as an original document. Code analysis tools like to process a lot of information, custom annotations can provide such information.
The data members in the annotation type are set to work with limited information. After you define a data member, you do not need to define the methods of access and modification separately. Instead, you just need to define a method that names it with the name of the member. The data type should be the type of the method return value. Listing 3 is a concrete example that clarifies some of the more ambiguous requirements:
Listing 3. Adding members to annotation types
package com.oreilly.tiger.ch06;
/**
* Annotation type to indicate a task still needs to be
* completed.
*/
public @interface TODO {
String value();
}