Annotations (Metadata)
-
embed metadata
in
source code, for
design-time/compile-time/run-time processing
-
Syntax -
@<annotation-name>(<member
initializations>)
-
the
bedrock of JEE
Annotation
Definition
-
Import
java.lang.annotation
package
-
@interface
-
indicates
an annotation type
-
annotation types automatically
extend Annotation
interface - specifies annotationType()
- returns a
Class
object representing
the invoking annotation.
-
use an
annotation to annotate
a declaration (classes,
methods, fields, parameters, enum
constants).
-
@Retention(RetentionPolicy)
- specify
when
an annotation is discarded. java.lang.annotation.RetentionPolicy
enum values:.
-
SOURCE
- retained only in source file - discarded in
compilation
-
CLASS
- stored in .class
file during compilation – discarded
by JVM during run
time.
-
RUNTIME
- stored in .class
file during compilation +
available through JVM during run time.
-
Note:
annotations
on local variables
are not retained.
-
@Documented
- marker to inform
tool that an annotation is to be documented.
-
@Target
- specifies types of declarations to which an annotation can be
applied – specified
by ElementType
enumeration: ANNOTATION_TYPE,
CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE
@Target( { ElementType.METHOD, ElementType.LOCAL_VARIABLE } )
-
@Inherited
– for class
annotations, causes the annotation for a superclass to be inherited
by a subclas.
-
annotation member default
values - add
default
clause to a member’s declaration – value
does not need to be specified when annotation is applied
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
String s() default "blah";
...
@MyAnnotation()
public void myMethod() {
-
Marker annotations
- contain no members, its presence as an annotation is sufficient –
can leave off
paranthesis on application
-
Single-member
annotations
-contain
only one member. can simply specify the value for that member —
don’t need to specify its
name , which
must be value.
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
int value(); // this variable name must be value
}
...
@MyAnnotation(111)
public void myMethod() {
Runtime
Usage
-
Import
java.lang.reflect
package
-
Obtain
annotations
(with
a retention policy of RUNTIME)
at
run-time
via
reflection
-
getClass( ) -
obtain a Class
object
-
Class<?>
- exposes reflection methods:
getMethod( ),
getField( ),
getConstructor(
) return
objects of type Method,
Field,
Constructor.
These objects expose
getAnnotation()
- obtain
specific annotation associated with that object
-
The
AnnotatedElement Interface
Methods:
getAnnotation(),
getAnnotations()
getDeclaredAnnotations(),
isAnnotationPresent(
)
-
getAnnotations( )
- obtain an array of
all annotations (that
have RUNTIME
retention)
that are associated with a reflection
object
-
eg
import java.lang.annotation.*;
import java.lang.reflect.*;
// definition
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
String s();
int i();
}
...
// application
class MyClass {
@MyAnnotation(s = "blah", i = 1)
public static void myMethod(String s, int i){}
}
...
// reflection
MyClass obj = new MyClass();
try {
Class<?> c = obj.getClass();
// param types for method signature must be specified:
Method m = c.getMethod("myMethod", String.class, int.class);
MyAnnotation a = m.getAnnotation(MyAnnotation.class);
System.out.println(a.s() + " " + a.i()); // annotation value getters
} catch (NoSuchMethodException ex) {}
JSE
Built-In Marker
Annotations