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、怎么获取类上的注解中的注解的注解的注解.....