Annotation元資料(一)我之心得
Annotation元資料(一)
一、Annotation究竟是什麼?
是java5.0中的新特徵
資料的資料(元資料)
Annotation和訪問修飾符一樣,應用於包、型別、構造方法、方法、成員變數、引數、本地變數的宣告中。
資訊以“name=value”方式儲存
annotation型別是一種介面,通過java反射方式進行訪問。
二、Annotation涉及的概念?
annotation:
是java5.0中新增的語法,它的行為十分類似public、final這樣的修飾符
annotation型別:
annotation型別定義了annotation的名字、型別、成員預設值。
一個annotation
annotation成員(是一個特殊的方法):
annotation的成員在annotation型別中以無引數的方法的形式被宣告。
可以有預設值(使用default關鍵字)
marker annotation型別:
沒有任何成員。
三、Java5.0中的標準Annotation
Override:
java.lang.Override是一個marker annotation型別,它被用作標註方法。
作用:說明了被標註的方法過載了父類的方法
使用場合:這個annotaton常常在我們試圖覆蓋父類方法而確又寫錯了方法名時發揮威力。
Deprecated:
是一個marker annotation
作用:用於標記已過期或不贊成使用的元素(如方法)
SuppressWarnings:
@SuppressWarnings被用於有選擇的關閉編譯器對類、方法、成員變數、變數初始化的警告。
serial
@SuppressWarnings("deprecation")
@SuppressWarnings(" unchecked ")
@Target 修飾的目標,是類、方法、欄位
@Retention 保留時間,編譯、執行
四、自定義Annotation語法
Public @interface 名稱{
Public 型別成員1() [default 預設值];
Public 型別成員2() [default
Public 型別成員3() [default 預設值];
}
返回型別
可以是基本資料型別,陣列和字串
不可以是日期型別
自定義Annotation語法
/**
* 表示Column是實現了java.lang.annotation.Annotation介面的一個類
* 註釋類與介面的區別
* 1) interface @interface
* 2)註釋的方法可帶預設值
* 3)指定Retention 在程式執行時仍然存在
* 4)指定Target 主要修飾方法
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Column
{
public String name();//返回資料庫表的欄位名
public int len() default 20;//返回欄位長度
public boolean unique(); //是否可空
}
例子1:自定義一個最簡單的Annotation——IfInvoke
package com.aptech.servlet;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public@interfaceIfInvoke {
publicboolean invoke();
}
注意:
@Retention(RetentionPolicy.RUNTIME):表示在執行時元資料還能被訪問
@interface:相當於實現了Annotation介面
Invoke:不需要實現的方法,並且返回型別有比較大的限制
例子2:自定義一個最簡單的Annotation——Employee(1)
Employee類的基本結構
package com.aptech.servlet;
import (匯入略)
publicclass Employee {
@IfInvoke(invoke = true)
publicvoid extraSalary(){
System.out.println("僱員是業務員,業務提成是:3000元");
}
}注意:
@IfInvoke(invoke = true):相當於invoke方法的返回值為true
呼叫程式碼:
Employee emp = new Employee();
try {
Method m = emp.getClass().getMethod("extraSalary", new Class[]{});
Annotation[] as = m.getAnnotations();
for(Annotation a : as){
if(a instanceofIfInvoke){
IfInvoke ii = (IfInvoke)a;
boolean b = ii.invoke();
if(b){
m.invoke(emp, new Object[]{});
}else{
System.out.println("不是業務員,不被呼叫");
}
}
}
} catch (Exception e1) {
e1.printStackTrace();
}
五、Annotation型別的annotation
Annotation型別可以被它們自己所標註。
Java5.0定義了4個標準的meta-annotation型別,它們被用來提供對其它annotation型別作說明。
這些型別和它們所支援的類在java.lang.annotation包中可以找到,主要有以下幾個:
Target
Retention
Documented
六、Target型別
Target
描述了annotation所修飾的程式成員的型別。
Target型別有唯一的value作為成員。這個成員的型別是ElementType[]型別的,ElementType型別是可以被標註的程式成員的列舉型別。
ElementType型別定義如下:
public enum ElementType {
TYPE,// Class, interface, or enum (but not annotation)
FIELD,// Field (including enumerated values)
METHOD,// Method (does not include constructors)
PARAMETER,// Method parameter
CONSTRUCTOR,// Constructor
LOCAL_VARIABLE,// Local variable or catch clause
ANNOTATION_TYPE,// Annotation Types (meta-annotations)
PACKAGE// Java package
}
七、Retention 型別
Retention描述了annotation是否被編譯器丟棄或者保留在class檔案中。
通常有幾種不同的選項:
將註釋保留在編譯後的類檔案中,並在第一次載入類時讀取它。
將註釋保留在編譯後的類檔案中,但是在執行時忽略它。
按照規定使用註釋,但是並不將它保留到編譯後的類檔案中。
這三種選項用 java.lang.annotation.RetentionPolicy 列舉表示。
public enum RetentionPolicy {
SOURCE,// Annotation is discarded by the compiler
CLASS,// Annotation is stored in the class file, but ignored by the VM
RUNTIME// Annotation is stored in the class file and read by the VM
}
預設情況下,annotation被儲存在class檔案中,但在執行時並不能被反射訪問。( RetentionPolicy. CLASS )
八、Documented型別
Documented 是一個標記註釋。
Documented 表示註釋應該出現在類的Javadoc 中。
例如
在IfInvoke註釋型別中,按如下定義:
@Retention(RetentionPolicy.RUNTIME)
public @interface IfInvoke {
public boolean invoke();
}
Employee類的extraSalary()方法生成的註釋如下:
public void extraSalary() [和普通沒什麼兩樣]
如果改成如下的定義方式:
@Documented
@Retention(RetentionPolicy.RUNTIME) //表示在執行時元資料還能被訪問
public @interface IfInvoke {
public boolean invoke();
}
Employee類的extraSalary()方法生成的註釋如下:
@IfInvoke(invoke=true)
public void extraSalary()
也就是說,javadoc工具會將Annotation抽取出並新增到HTML檔案中。