Table of Contents
This section provides the essential information about annotations in Java 5 needed to understand how annotations are treated in AspectJ 5. For a full introduction to annotations in Java, please see the documentation for the Java 5 SDK.
Java 5 introduces annotation types which can be used to express metadata relating to program members in the form of annotations. Annotations in Java 5 can be applied to package and type declarations (classes, interfaces, enums, and annotations), constructors, methods, fields, parameters, and variables. Annotations are specified in the program source by using the @ symbol. For example, the following piece of code uses the @Deprecated annotation to indicate that the obsoleteMethod() has been deprecated:
@Deprecated public void obsoleteMethod() { ... }
Annotations may be marker annotations, single-valued annotations, or multi-valued annotations. Annotation types with no members or that provide default values for all members may be used simply as marker annotations, as in the deprecation example above. Single-value annotation types have a single member, and the annotation may be written in one of two equivalent forms:
@SuppressWarnings({"unchecked"}) public void someMethod() {...}
or
@SuppressWarnings(value={"unchecked"}) public void someMethod() {...}
Multi-value annotations must use the member-name=value syntax to specify annotation values. For example:
@Authenticated(role="supervisor",clearanceLevel=5) public void someMethod() {...}
Annotations can have one of three retention policies:
Annotations with source-file retention are read by the compiler during the compilation process, but are not rendered in the generated .class files.
This is the default retention policy. Annotations with class-file retention are read by the compiler and also retained in the generated .class files.
Annotations with runtime retention are read by the compiler, retained in the generated .class files, and also made available at runtime.
Local variable annotations are not retained in class files (or at runtime) regardless of the retention policy set on the annotation type. See JLS 9.6.1.2.
Java 5 supports a new interface, java.lang.reflect.AnnotatedElement, that is implemented by the reflection classes in Java (Class, Constructor, Field, Method, and Package). This interface gives you access to annotations that have runtime retention via the getAnnotation, getAnnotations, and isAnnotationPresent. Because annotation types are just regular Java classes, the annotations returned by these methods can be queried just like any regular Java object.
It is important to understand the rules relating to inheritance of annotations, as these have a bearing on join point matching based on the presence or absence of annotations.
By default annotations are not inherited. Given the following program
@MyAnnotation class Super { @Oneway public void foo() {} } class Sub extends Super { public void foo() {} }
Then Sub does not have the MyAnnotation annotation, and Sub.foo() is not an @Oneway method, despite the fact that it overrides Super.foo() which is.
If an annotation type has the meta-annotation @Inherited then an annotation of that type on a class will cause the annotation to be inherited by sub-classes. So, in the example above, if the MyAnnotation type had the @Inherited attribute, then Sub would have the MyAnnotation annotation.
@Inherited annotations are not inherited when used to annotate anything other than a type. A type that implements one or more interfaces never inherits any annotations from the interfaces it implements.