AnnotatedElement是Java反射中的一個接口,其中提供了很多獲取注解的方法,以下是AnnotatedElement接口中的方法列表:
directly present、indirectly present、present、associated
首先需要熟悉四種關系(元素與注解)
1、directly present
直接存在或者翻譯為直接引用。當一個注解直接在元素上引用時,則為直接引用,比如下面代碼,@Action就是直接引用:
-- snip --
@Action("上課")
public class Student {
-- snip --
}
2、indirectly present
間接存在或間接引用。當一個注解A並沒有注解引用在一個類E上,但是包含這個注解A的注解B被E直接引用了,這屬於E對A的間接引用。可參考下面實例。
3、present
引用。有兩種情況都屬於引用類型,
- directly present關系肯定是present
- 一個注解A(為可繼承的,用@Inherited標識注解)直接引用於E類的超類F,那么E與A的關系則為引用關系
4、associated
關聯。存在四種情況則為關聯關系。
- 直接引用關系
- 間接引用關系
- 引用關系
- 一個注解A(為可繼承的,用@Inherited標識注解)與E類的超類F相關聯,那么E與A的關系也為關聯關系
實例驗證
package com.leadmap.java.entity;
import com.leadmap.java.annotation.Gender;
import com.leadmap.java.annotation.Hobby;
import com.leadmap.java.annotation.Hobbys;
import com.leadmap.java.annotation.Identity;
import java.lang.annotation.Annotation;
/**
* Company: XXXXXX
*
* @description: xxx
* @author: banmao
* @date: 2022/1/6 15:04
*/
@Hobby(value = "籃球")
@Hobby(value = "台球")
@Gender(type = "女")
public class People extends Human {
public static void main(String[] args) {
// 獲取注解數組(只獲取直接引用到類上的注解),
getDeclaredAnnotations(People.class);
// 獲取引用關系的注解數組,@Action、@Identity注解與People為引用關系
getAnnotations(People.class);
// 通過類型獲取注解,Hobbys注解與People為間接引用關系
getAnnotationByType(People.class, Hobbys.class);
// 通過類型獲取注解,@Identity與People為關聯關系
getAnnotationByType(People.class, Identity.class);
}
/**
* 獲取callObj元素上<em>directly present</em>關系注解的數組
*
* @param callObj 被測試的元素
*/
private static void getDeclaredAnnotations(Class<?> callObj) {
System.out.println("---------------getDeclaredAnnotations----------------");
Annotation[] annotations = callObj.getDeclaredAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation.annotationType().getName());
}
System.out.println();
}
/**
* 獲取callObj元素上<em>present</em>關系注解的數組
*
* @param callObj 被測試的元素
*/
private static void getAnnotations(Class<?> callObj) {
System.out.println("---------------getAnnotations----------------");
Annotation[] annotations = callObj.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation.annotationType().getName());
}
System.out.println();
}
/**
* 獲取callObj元素上<em>associated</em>關系注解的數組
*
* @param callObj 被測試的元素
* @param queryAnnotation 要被查詢的注解
*/
private static void getAnnotationByType(Class<?> callObj, Class<? extends Annotation> queryAnnotation) {
System.out.println("---------------getAnnotationByType----------------");
Annotation[] annotations = callObj.getAnnotationsByType(queryAnnotation);
for (Annotation annotation : annotations) {
System.out.println(annotation.annotationType().getName());
}
System.out.println();
}
}
package com.leadmap.java.entity;
import com.leadmap.java.annotation.Action;
/**
* Company: XXXXXX
*
* @description:
* @author: banmao
* @date: 2022/1/6 16:00
*/
@Action(value = "行走")
public class Human extends Nuwa {
}
package com.leadmap.java.entity;
import com.leadmap.java.annotation.Identity;
/**
* @author banmao
* @version V1.0.0
* @date 2022/1/6 下午9:06
* @description 女媧造人
*/
@Identity(value = "造物者")
public class Nuwa {
}
-- snip --
以上將注解相關代碼省略了,People中main方法運行結果如下,需要注意的是在Hobby注解中使用@Repeatable(value = Hobbys.class)實現的可重復注解,在解析時,表現的形式其實類似於Hobbys{Hobby1.class,Hobby2.class}
,所以以下獲取到直接引用的注解為Hobbys注解。
思考
1、如果People是個泛型類,類型參數使用的注解能獲取到嗎?
2、實例中使用的都是extends來實現注解的繼承,如果是implements實現一個接口呢?
經驗證,不行
3、怎么獲取類上的注解中的注解的注解的注解.....