要聲明一個註解, 咱們須要元註解, 元註解是指註解的註解,包括@Retention
, @Target
, @Document
, @Inherited
.java
@Retention
註解的保留位置(枚舉RetentionPolicy),RetentionPolicy可選值:ide
SOURCE
註解僅存在於源碼中,在class字節碼文件中不包含, 若是隻是作一些檢查性的操做,好比 @Override 和 @SuppressWarnings,則可選用 SOURCE 註解。CLASS
默認的保留策略,註解在class字節碼文件中存在,但運行時沒法得到, 若是要在編譯時進行一些預處理操做,好比生成一些輔助代碼(如 ButterKnife),就用 CLASS註解RUNTIME
註解在class字節碼文件中存在,在運行時能夠經過反射獲取到, 若是須要在運行時去動態獲取註解信息,那隻能用 RUNTIME 註解@Inherited
說明子類能夠繼承父類中的該註解函數
@Documented
聲明註解可以被javadoc等識別測試
@Target
用來聲明註解範圍(枚舉ElementType),ElementType可選值:code
TYPE
接口、類、枚舉、註解FIELD
字段、枚舉的常量METHOD
方法PARAMETER
方法參數CONSTRUCTOR
構造函數LOCAL_VARIABLE
局部變量ANNOTATION_TYPE
註解PACKAGE
包@Target(value = ElementType.METHOD) //聲明該註解的運行目標: 方法 @Retention(value = RetentionPolicy.RUNTIME) //該註解的生命週期: 運行時 public @interface CanRun { // 經過@interface表示註解類型 String str() default "wow"; // 註解中攜帶的元數據 }
public class AnnotationRunner { public void method1() { System.out.println("method 1"); } @CanRun(str = "foobar") // 方法2添加了自定義註解的標籤同時傳入str值 public void method2() { System.out.println("method 2"); } public void method3() { System.out.println("method 3"); } }
public class AnnotationTest { public static void main(String[] args) throws InvocationTargetException, IllegalAccessException { AnnotationRunner runner = new AnnotationRunner(); Method[] methods = runner.getClass().getMethods(); for (Method method : methods){ CanRun annos = method.getAnnotation(CanRun.class); //System.out.println("1"); if (annos != null){ method.invoke(runner); System.out.println(annos.str()); } } } }
運行結果:繼承
method 2 foobar