來看一個最簡單的annotation
package com.cts.elt.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
importjava.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAnnotation1 {
String value();
}
1. Annotation需要聲明為@interface這樣的東西
2. @Target(ElementType.TYPE)
代碼這個annotation必須且一定要注釋在什麼語句上面
ElementType.TYPE代表此Annotation必須聲明在public class Student{…}的上面,而不能寫在任何的method{}(方法)或者是field(屬性)的上方。
@Target: 表示該注解可以用于什麼地方。可用ElementType枚舉類型主要有:
TYPE : 類、接口或enum聲明
FIELD: 域(屬性)聲明
METHOD: 方法聲明
PARAMETER: 參數聲明
CONSTRUCTOR: 構造方法聲明
LOCAL_VARIABLE:局部變量聲明
ANNOTATION_TYPE:注釋類型聲明
PACKAGE: 包聲明
3. Retention如果設為了RUNTIME,代表此annotation的具體實作可以在運作時用類反射來實作
我們看到了,annotation一般為一個@interface,也沒啥具體的implementation(實作)
怎麼實作這個annotation呢?類反射
@Retention: 表示需要在什麼級别儲存該注解資訊。
可用RetentionPolicy枚舉類型主要有:
SOURCE: 注解将被編譯器丢棄。
CLASS : 注解在class檔案中可能。但會被VM丢棄。
RUNTIME: VM将在運作時也儲存注解(如果需要通過反射讀取注解,則
使用該值)。
4. @Documented
@Documented: 将此注解包含在Javadoc中。
上面這個MyAnnotation1.class檔案包含一個值,下面來一個含有兩個值的annotation
@Target(ElementType.METHOD)
public @interface MyAnnotation2 {
String description();
boolean isAnnotation();
關鍵是來看這兩個自定義annotation的用法:
@MyAnnotation1("this isannotation1")
public class AnnotationDemo {
@MyAnnotation2(description = "this is annotation2", isAnnotation =true)
public void sayHello() {
System.out.println("hello world!");
}
如果把@MyAnnotation1與@MyAnnotation2的位置換一換,會怎麼樣?請自己動手在eclipse裡試試看,嘿嘿,就知道這個Retention的用法了
首先,網上的一些關于自定義annotation教程所舉的例子都不太好!
就2個例子,然後一幫子人在那邊到處COPY這兩個例子然後到處轉發,搞得來大家雲裡霧裡一頭霧水,同時一群企業的面試官也就喜歡拿這個自定義annotation來作面試題,好像會個annotation就能給Senior software engineer了。
其實Annotation就是類反射加點枚舉,比個資料結構裡的冒泡排序還簡單,沒這麼誇張,關鍵是例子舉的不好,現在來看看下面這個例子。
Hibernate的機制是可能通過JAVA類然後逆向成資料庫裡的某個表,大家還記得吧?
比如說
Student.java檔案
如果你這樣寫:
@Table(name=”T_STUDENT”)
Public class Student{…}
代表這個類對應的資料庫表叫T_STUDENT
如果再有下面這樣的寫法:
Public class Student{
Private String id=””;
@Id(init=1)
Public voidsetName(String id){
This.id=id;
就代表id這個field是一個主鍵,它的初始值為1。
好了,現在開始我們自己的例子,設有一CLASS叫Student,其中有三個fields:
private String name = "";
private int age = 0;
private String studentId = "";
相應的每一個field有一對的set, get方法
然後我在每個set方法上造一個annotation叫ValueBind的注解,其作用是:
隻要set方法上帶有ValueBind注解,它就會根據這個字段的類型把一個預設值,自動賦給Student類中相對應的field。
先來看一下Student類:
import java.io.Serializable;
importcom.cts.elt.annotation.ValueBind.fieldType;
public class Student implementsSerializable {
private String name = "";
public String getName() {
return name;
@ValueBind(type = fieldType.STRING, value ="aa")
public void setName(String name) {
this.name = name;
public int getAge() {
return age;
@ValueBind(type = fieldType.INT, value ="30")
public void setAge(int age) {
this.age = age;
public String getStudentId() {
return studentId;
@ValueBind(type = fieldType.STRING, value ="101")
public void setStudentId(String studentId) {
this.studentId = studentId;
private int age = 0;
private String studentId = "";
這個@ValueBoind就是我的自定義的annotation,裡面有兩個值,來看這個annotation是怎麼做的吧:
public @interface ValueBind {
enum fieldType {
STRING, INT
};
fieldType type();
夠簡單的吧!
首先這個annotation隻能被标注在方法上
其次它含有兩個值,一個是enum類型,一個是String類型
現在來看我們真正的實作(用類反射來實作)
import java.lang.reflect.*;
public class PersistStudent {
public static void main(String[] args) throws Exception {
Object c = Class.forName("com.cts.elt.annotation.Student")
.newInstance();
try {
Method[] methodArray = c.getClass().getDeclaredMethods();
for (int i = 0; i < methodArray.length; i++) {
if (methodArray[i].isAnnotationPresent(ValueBind.class)) {
ValueBind annotation = methodArray[i]
.getAnnotation(ValueBind.class);
String type = String.valueOf(annotation.type());
String value = annotation.value();
if (type.equals("INT")) {
methodArray[i].invoke(c, new Integer[] { new Integer(
value) });
} else {
methodArray[i].invoke(c, new String[] { value });
}
}
}
Student annotaedStudent = (Student) c;
System.out.println("studentId====" + annotaedStudent.getStudentId()
+ " studentnName====" + annotaedStudent.getName()
+ " student Age====" + annotaedStudent.getAge());
} catch (Exception e) {
throw new Exception(e);
}
運作完畢後顯示:
studentId====101 studentnName====aa studentAge====30
自己把代碼敲到eclipse裡後再去感受一下吧,馬上讓你annotation入門