Reference Doc,
Official Site: http://java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html
CSDN Site: http://blog.csdn.net/numberpig/archive/2006/08/18/1095144.aspx
Quick Start
Example: we want to map the JavaBean user with the DB2 table USER
1) TableInfo Annotation
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface TableInfo { String value(); // Element declaration }
2) FieldInfo Annotation
// set to Runtime, then we can load those Annotation info by jave reflection @Retention(RetentionPolicy.RUNTIME) @Documented public @interface FieldInfo { String FieldName(); Class<?> FieldType(); String FieldOper(); }
3) JavaBean User.java
@TableInfo("USER") public class User { private String name = null; private Date birth = null; @FieldInfo(FieldName="USERNAME", FieldType=String.class, FieldOper="SET") public void setName(String name){ this.name = name; } @FieldInfo(FieldName="USERNAME", FieldType=String.class, FieldOper="GET") public String getName(){ return this.name; } @FieldInfo(FieldName="BIRTHDAY", FieldType=Date.class, FieldOper="SET") public void setBirth(Date date){ this.birth = date; } @FieldInfo(FieldName="BIRTHDAY", FieldType=Date.class, FieldOper="GET") public Date getBirth(Date date){ return this.birth; } }
3) Test get Annotation Info
@Test public void UserInfoTest() throws ClassNotFoundException, IllegalAccessException, InstantiationException{ String className = "annotation.User"; Class<User> urClass = User.class; // for type safe User u = urClass.cast( Class.forName(className).newInstance() ); if ( u.getClass().isAnnotationPresent( TableInfo.class ) ){ TableInfo tf = urClass.getAnnotation( TableInfo.class ); assertTrue("DB table is USER", "USER".equalsIgnoreCase(tf.value())); } Method[] methods = urClass.getMethods(); for(Method m : methods){ FieldInfo finfo = null; if(m.isAnnotationPresent( FieldInfo.class ) && m.getName().indexOf("Name") >= 0 ){ finfo = m.getAnnotation( FieldInfo.class ); assertTrue("DB Field Name is USERNAME", "USERNAME".equals(finfo.FieldName())); assertTrue("DB varchar mapping with String", String.class == finfo.FieldType() ); if(m.getName().equals("getName")) assertTrue("Operation is Set", "GET".equals(finfo.FieldOper())); if(m.getName().equals("setName")) assertTrue("Operation is Get", "SET".equals(finfo.FieldOper())); } if(m.isAnnotationPresent( FieldInfo.class ) && m.getName().indexOf("Birth") >= 0 ){ finfo = m.getAnnotation( FieldInfo.class ); assertTrue("DB Field Name is BIRTHDAY", "BIRTHDAY".equals(finfo.FieldName())); assertTrue("DB Date mapping with Date", Date.class == finfo.FieldType() ); if(m.getName().equals("getBirth")) assertTrue("Operation is Set", "GET".equals(finfo.FieldOper())); if(m.getName().equals("SetBirth")) assertTrue("Operation is Get", "SET".equals(finfo.FieldOper())); } } }
Annotation Defination,
Annotation Type
/** * Describes the Request-For-Enhancement(RFE) that led * to the presence of the annotated API element. */ public @interface RequestForEnhancement { int id(); // annotation element declearation, id is the name, int is type String synopsis(); String engineer() default "[unassigned]"; String date(); default "[unimplemented]"; }
Annotation type declarations are similar to normal interface declarations
a. Each method declaration defines an element of the annotation type.
b. Method declarations must not have any parameters or a throws
clause
c. Return types are restricted to primitives, String
, Class
, enums, annotations, and arrays of the preceding types
d. Methods can have default values
Annotation
@RequestForEnhancement( id = 2868724 // annotate the element declaration synopsis = "Enable time-travel", engineer = "Mr. Peabody", date = "4/1/3007" ) public static void travelThroughTime(Date destination) { ... }
An annotation is a special kind of modifier, and can be used anywhere that other modifiers (such as public
, static
, or final
) can be used, and precede other modifiers
a. Annotations consist of an at-sign (@
) followed by an annotation type and a parenthesized list of element-value pairs
b. The values must be compile-time constants.
Marker_Annotation_Type
The Annotation Type with no elements
/** * Indicates that the specification of the annotated API element * is preliminary and subject to change. */ public @interface Preliminary { }
Meta-Annotation
Meta-Annotation is a special kind of Annotation to declare the Annotation Type
1. Target Meta-Annotation
Target Annotation Type Source Code
@Documented // Copy the message of this Annotation Type into Java API @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Target { ElementType[] value(); }
ElementType Source code
public enum ElementType { TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, ANNOTATION_TYPE,PACKAGE }
it defines the following,
a. Defined the effective scale(On Method, FIELD......) of the annotation declared by Target.
Example
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Name { String originate(); String community(); }
The Annotation "Name" can only effect on Method level
Focus that, if the Annotation didn't specify the Target, the Annotation effect on any level declare in ElementType
2. Rentation Meta-Annotation
Rentation Source Code
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Retention { RetentionPolicy value(); }
RetationPolicy Source Code
public enum RetentionPolicy { SOURCE, CLASS, RUNTIME }
It defines the annotation active scare,
a. SOURCE - the annotation only retained in Source code, after complie, it will lost
b. CLASS - the annotation retained in both Souce code and Classes
c. RUNTIM - the annotaion reatined in both above, and it will be loaded into JVM. Then we can use the Reflection to retrieve the annotation info.