|
In this section, we cover everything you need to know about the annotation syntax. An annotation is defined by an annotation interface:
Each element declaration has the form
or
For example, the following annotation has two elements, assignedTo and severity. public @interface BugReport { String assignedTo() default "[none]"; int severity() = 0; } Each annotation has the format
For example, @BugReport(assignedTo="Harry", severity=10) The order of the elements does not matter. The annotation @BugReport(severity=10, assignedTo="Harry") is identical to the preceding one. The default value of the declaration is used if an element value is not specified. For example, consider the annotation @BugReport(severity=10) The value of the assignedTo element is the string "[none]". CAUTION
Two special shortcuts can simplify annotations. If no elements are specified, either because the annotation doesn't have any or because all of them use the default value, then you don't need to use parentheses. For example, @BugReport is the same as @BugReport(assignedTo="[none]", severity=0) Such an annotation is called a marker annotation. The other shortcut is the single value annotation. If an element has the special name value, and no other element is specified, then you can omit the element name and the = symbol. For example, had we defined the ActionListenerFor annotation interface of the preceding section as public @interface ActionListenerFor { String value(); } then we could have written the annotations as @ActionListenerFor("yellowButton") instead of @ActionListenerFor(value="yellowButton") All annotation interfaces implicitly extend the interface java.lang.annotation.Annotation. That interface is a regular interface, not an annotation interface. See the API notes at the end of this section for the methods provided by this interface. You cannot extend annotation interfaces. In other words, all annotation interfaces directly extend java.lang.annotation.Annotation. You never supply classes that implement annotation interfaces. Instead, the virtual machine generates proxy classes and objects when needed. For example, when requesting an ActionListenerFor annotation, the virtual machine carries out an operation similar to the following:
The element declarations in the annotation interface are actually method declarations. The methods of an annotation interface can have no parameters and no throws clauses, and they cannot be generic. The type of an annotation element is one of the following:
NOTE
Here are examples for valid element declarations: public @interface BugReport { enum Status { UNCONFIRMED, CONFIRMED, FIXED, NOTABUG }; boolean showStopper() default false; String assignedTo() default "[none]"; Class<? extends Testable> testCase() default Testable.class; Status status() default Status.UNCONFIRMED; TestCase testCase(); String[] reportedBy(); } Because annotations are evaluated by the compiler, all element values must be compile-time constants. For example, @BugReport(showStopper=true, assignedTo="Harry", testCase=MyTestCase.class, status=BugReport.Status.CONFIRMED, . . .) CAUTION
If an element value is an array, you enclose its values in braces, like this: @BugReport(. . ., reportedBy={"Harry", "Carl"}) You can omit the braces if the element has a single value: @BugReport(. . ., reportedBy="Joe") // OK, same as {"Joe"} Since an annotation element can be another annotation, you can build arbitrarily complex annotations. For example, @BugReport(testCase=@TestCase(), . . .) NOTE
You can add annotations to the following items:
However, annotations for local variables can only be processed at the source level. Class files do not describe local variables. Therefore, all local variable annotations are discarded when a class is compiled. Similarly, annotations for packages are not retained beyond the source level. NOTE
An item can have multiple annotations, provided they belong to different types. You cannot use the same annotation type more than once when annotating a particular item. For example, @BugReport(showStopper=true, reportedBy="Joe") @BugReport(reportedBy={"Harry", "Carl"}) void myMethod() is a compile-time error. If this is a problem, you can design an annotation whose value is an array of simpler annotations: @BugReports({ @BugReport(showStopper=true, reportedBy="Joe"), @BugReport(reportedBy={"Harry", "Carl"})) void myMethod() java.lang.annotation.Annotation 5.0
|
|