元注解
要聲明一個注解, 我們需要元注解, 元注解是指注解的注解,包括@Retention
, @Target
, @Document
, @Inherited
.
@Retention
注解的保留位置(枚舉RetentionPolicy),RetentionPolicy可選值:
SOURCE
注解僅存在於源碼中,在class字節碼文件中不包含, 如果只是做一些檢查性的操作,比如 @Override 和 @SuppressWarnings,則可選用 SOURCE 注解。CLASS
默認的保留策略,注解在class字節碼文件中存在,但運行時無法獲得, 如果要在編譯時進行一些預處理操作,比如生成一些輔助代碼(如 ButterKnife),就用 CLASS注解RUNTIME
注解在class字節碼文件中存在,在運行時可以通過反射獲取到, 如果需要在運行時去動態獲取注解信息,那只能用 RUNTIME 注解
@Inherited
說明子類可以繼承父類中的該注解
@Documented
聲明注解能夠被javadoc等識別
@Target
用來聲明注解范圍(枚舉ElementType),ElementType可選值:
TYPE
接口、類、枚舉、注解FIELD
字段、枚舉的常量METHOD
方法PARAMETER
方法參數CONSTRUCTOR
構造函數LOCAL_VARIABLE
局部變量ANNOTATION_TYPE
注解PACKAGE
包
Demo
1.聲明注解類型
@Target(value = ElementType.METHOD) //聲明該注解的運行目標: 方法
@Retention(value = RetentionPolicy.RUNTIME) //該注解的生命周期: 運行時
public @interface CanRun { // 通過@interface表示注解類型
String str() default "wow"; // 注解中攜帶的元數據
}
2.使用自定義注解
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");
}
}
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