What Are Annotations?
In short, annotations are metadata or data about data. Annotations are said to annotate a Java element. An annotation indicates that the declared element should be processed in some special way by a compiler, development tool, deployment tool, or during runtime.
Annotations can be analyzed statically before and during compile time. Annotations will likely be used before compile time mainly to generate supporting classes or configuration files.For example, a code generator (XDoclet, for example) can use annotation data in an EJB implementation class to generate EJB interfaces and deployment descriptors for you, reducing both your effort and the error rate. The average developer will probably not be writing code-generation tools, so these annotation types are likely to be used out-of-the-box rather than authored anew.
Annotations will also be used for compile-time checking such as to produce warnings and errors for different failure scenarios. An example of an annotation that is used at compile time is the new @Deprecated annotation, which acts the same as the old @deprecated JavaDoc tag.
Annotations can be useful at runtime as well. Using annotations you could mark code to behave in a particular way whenever it is called.For example, you could mark some methods with a @prelog annotation.
Another way to use annotations at runtime is to use Aspect-Oriented Programming (AOP). AOP uses pointcuts—sets of points configured to executed aspects. You could define a pointcut that will execute an aspect for an annotated method. My guess is that developers would be more likely to write their own runtime annotation types than they would annotation types used for code generation and compile-time checking. Still, writing and understanding the code that accesses the annotations (the annotation consumer) at runtime is fairly advanced.
Annotating Code
Annotations fall into three categories: normal annotations, single member annotations, and marker annotations (see Table 1). Normal and single member annotations can take member values as arguments when you annotate your code.
1. Normal Annotations—Annotations that take multiple arguments. The syntax for these annotations provides the ability to pass in data for all the members defined in an annotation type.
Example: @MyNormalAnnotation(mem1="val1", mem2="val2") public void someMethod() { ... }
2. Single Member Annotations—An annotation that only takes a single argument has a more compact syntax. You don't need to provide the member name.
Example: @MySingleMemberAnnotation("a single value") public class SomeClass { ... }
3.Marker Annotations—These annotations take no parameters. They are used to mark a Java element to be processed in a particular way.
Example: @Deprecated public void doWork() { ... }
Any Java declaration can be marked with an annotation. That is, an annotation can be used on a: package, class, interface, field, method, parameter, constructor, enum (newly available in Java 1.5), or local variable. An annotation can even annotate another annotation. Such annotations are called meta-annotations.
Packages annotations are also allowed, but because packages are not explicitly declared in Java, package annotations must be declared in a source file called package-info.java in the directory containing the source files for the package.
Built-in Annotations
Java 1.5 comes packaged with seven pre-built annotations.
(The follows are meta-annotation.)
Declaring Annotation Types
Now that you've learned a little about the annotations that come packaged with Java 1.5, you can move on to declaring your own annotation types.
Here is a sample annotation type:
public @interface MyAnnotationType {
int someValue();
String someOtherValue();
String yesSomeOtherValue() default "[blank]";
}
The annotation consumers are the development tools, the compiler, or a runtime library that accesses the annotation data you created when you annotated your Java code.
An example of how you can access your code during runtime using the reflection API.
// The Annotation Type
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Retention(RUNTIME)
public @interface GreetsTheWorld {
public String value();
}
// The Annotated Class
@GreetsTheWorld("Hello, class!")
public class HelloWorld {
@GreetsTheWorld("Hello, field!")
public String greetingState;
@GreetsTheWorld("Hello, constructor!")
public HelloWorld() {
}
@GreetsTheWorld("Hello, method!")
public void sayHi() {
}
}
// The Annotation Consumer
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class HelloWorldAnnotationTest
{
public static void main( String[] args ) throws Exception
{
//access the class annotation
Classclazz = HelloWorld.class;
System.out.println( clazz.getAnnotation( GreetsTheWorld.class ) );
//access the constructor annotation
Constructorconstructor =
clazz.getConstructor((Class[]) null);
System.out.println(
constructor.getAnnotation(GreetsTheWorld.class));
//access the method annotation
Method method = clazz.getMethod( "sayHi" );
System.out.println(method.getAnnotation(GreetsTheWorld.class));
//access the field annotation
Field field = clazz.getField("greetingState");
System.out.println(field.getAnnotation(GreetsTheWorld.class));
}
}
No comments:
Post a Comment