Reference Doc,
Official Site: http://java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html
优快云 Site: http://blog.youkuaiyun.com/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.