如果想获取一个类的所有修饰符的方法,包括所有父类中的方法,那么建议递归调用getDeclaredMethods()(所谓递归调用就是一直追溯目标类的父类递归调用getDeclaredMethods()方法直到父类为Object类型,这个思路可以参考Spring框架中的相关工具类)。获取一个类的所有Field、Constructor也可以类似操作,可以参考或者直接使用Spring中的工具类ReflectionUtils的相关方法。@Inherited元注解是一个标记注解,@Inherited阐述了某个被标注的Annotation类型是可以被继承的,详细的在分析AnnotatedElement的时候再展开。
Type接口java.lang.reflect.Type接口是Java中所有类型的共同父类,这些类型包括原始类型、泛型类型、数组类型、类型变量和基本类型,接口定义如下:
public interface Type { default String getTypeName() { return toString(); } } AnnotatedElement接口AnnotatedElement是一个接口,它定义的方法主要和注解操作相关,例如用于判断注解的存在性和获取注解等等。
方法 功能boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) 判断指定的注解类型在当前的实例上是否存在
<T extends Annotation> T getAnnotation(Class<T> annotationClass) 获取当前实例上指定注解类型的注解实例,不存在时返回null
Annotation[] getAnnotations() 获取当前实例上所有注解实例,包括继承获得的注解,不存在则返回长度为0的数组
<T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) 获取当前实例上指定注解类型的注解实例,不包括继承获得的注解,不存在则返回长度为0的数组
<T extends Annotation> T[] getDeclaredAnnotations(Class<T> annotationClass) 获取当前实例上所有的注解实例,不包括继承获得的注解,不存在则返回长度为0的数组
<T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) 在不使用@Repeatable的时候,功能和getDeclaredAnnotations方法一致,如果使用了@Repeatable,则合并解析@Repeatable后的结果
<T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) 如果指定annotationClass注解类型可继承(使用了@Inherited),那么递归调用getDeclaredAnnotationsByType
举个简单例子:
public class Main { public static void main(String[] args) { Class<?> clazz = Sub.class; System.out.println("-----getAnnotations-----"); Annotation[] annotations = clazz.getAnnotations(); for (Annotation annotation : annotations) { System.out.println(annotation.toString()); } System.out.println("-----getDeclaredAnnotation-->SupperAnnotation-----"); SupperAnnotation declaredSupperAnnotation = clazz.getDeclaredAnnotation(SupperAnnotation.class); System.out.println(declaredSupperAnnotation); System.out.println("-----getAnnotation-->SupperAnnotation-----"); SupperAnnotation supperAnnotation = clazz.getAnnotation(SupperAnnotation.class); System.out.println(supperAnnotation); System.out.println("-----getDeclaredAnnotation-->SubAnnotation-----"); SubAnnotation declaredSubAnnotation = clazz.getDeclaredAnnotation(SubAnnotation.class); System.out.println(declaredSubAnnotation); System.out.println("-----getDeclaredAnnotationsByType-->SubAnnotation-----"); SubAnnotation[] declaredSubAnnotationsByType = clazz.getDeclaredAnnotationsByType(SubAnnotation.class); for (SubAnnotation subAnnotation : declaredSubAnnotationsByType) { System.out.println(subAnnotation); } System.out.println("-----getDeclaredAnnotationsByType-->SupperAnnotation-----"); SupperAnnotation[] declaredSupperAnnotationsByType = clazz.getDeclaredAnnotationsByType(SupperAnnotation.class); for (SupperAnnotation supperAnnotation1 : declaredSupperAnnotationsByType) { System.out.println(supperAnnotation1); } System.out.println("-----getAnnotationsByType-->SupperAnnotation-----"); SupperAnnotation[] supperAnnotationsByType = clazz.getAnnotationsByType(SupperAnnotation.class); for (SupperAnnotation supperAnnotation2 : supperAnnotationsByType) { System.out.println(supperAnnotation2); } } @SupperAnnotation private static class Supper { } @SubAnnotation private static class Sub extends Supper { } @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented @Target(ElementType.TYPE) private @interface SupperAnnotation { String value() default "SupperAnnotation"; } @Retention(RetentionPolicy.RUNTIME) @Documented @Target(ElementType.TYPE) private @interface SubAnnotation { String value() default "SubAnnotation"; } }