栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java源码分析-注解AnnotatedElement接口

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java源码分析-注解AnnotatedElement接口

java源码分析-注解AnnotatedElement接口 概述

在我们讲解注解的运行时处理器时写过这样一段代码:

 //通过Class对象拿到getPersonInfo方法对象Method
Method method = clazz.getDeclaredMethod("getPersonInfo", null);
System.out.println(method.getName());
//根据Method获取到该方法上的注解
MyPersonAnnotation declaredAnnotations = method.getDeclaredAnnotation(MyPersonAnnotation.class);
System.out.println(declaredAnnotations);

​ 其中通过调用Method对象的getAnnotation(MyPersonAnnotation.class)获取该方法上的注解信息,这是典型的通过反射来获取信息的。有个问题,注解和反射是怎么关联上的呢?

​ 其实先要弄明白其中的原理,关键点就在AnnotatedElement接口中。AnnotatedElement接口表示当前运行的虚拟机中一个可以被注解的元素,它提供了一些抽象方法,允许通过反射读取到被注解的元素上的注解信息。

​ 我们看一下这个接口的类图:

通过上图我们知道:

子接口
  • AnnotatedType:被注解的类型;
  • AnnotatedTypeVariable:被注解的类型变量;
  • AnnotatedArrayType:被注解的数组类型;
  • AnnotatedParamerizedType:被注解的参数化类型;
  • AnnotatedWildcardType:被注解的通配类型;
  • GenericDeclaration:通用声明,用于表示声明类型元素,如:类、方法、构造器等;
实现类
  • AccessibleObject:可访问的对象,如:方法、构造器、属性等;
  • Class:类;
  • Constructor:构造器;
  • Executable:可执行的,如构造器和方法;
  • Field:字段属性;
  • Method:方法;
  • Package:包;
  • Parameter:参数;
方法

AnnotatedElement源码如下:

public interface AnnotatedElement {
    
    default boolean isAnnotationPresent(Class annotationClass) {
        return getAnnotation(annotationClass) != null;
    }

   
     T getAnnotation(Class annotationClass);

    
    Annotation[] getAnnotations();

   
    default  T[] getAnnotationsByType(Class annotationClass) {
         
         T[] result = getDeclaredAnnotationsByType(annotationClass);

         if (result.length == 0 && // Neither directly nor indirectly present
             this instanceof Class && // the element is a class
             AnnotationType.getInstance(annotationClass).isInherited()) { // Inheritable
             Class superClass = ((Class) this).getSuperclass();
             if (superClass != null) {
                 // Determine if the annotation is associated with the
                 // superclass
                 result = superClass.getAnnotationsByType(annotationClass);
             }
         }

         return result;
     }

    
    default  T getDeclaredAnnotation(Class annotationClass) {
         Objects.requireNonNull(annotationClass);
         // Loop over all directly-present annotations looking for a matching one
         for (Annotation annotation : getDeclaredAnnotations()) {
             if (annotationClass.equals(annotation.annotationType())) {
                 // More robust to do a dynamic cast at runtime instead
                 // of compile-time only.
                 return annotationClass.cast(annotation);
             }
         }
         return null;
     }

    
    default  T[] getDeclaredAnnotationsByType(Class annotationClass) {
        Objects.requireNonNull(annotationClass);
        return AnnotationSupport.
            getDirectlyAndIndirectlyPresent(Arrays.stream(getDeclaredAnnotations()).
                                            collect(Collectors.toMap(Annotation::annotationType,
                                                                     Function.identity(),
                                                                     ((first,second) -> first),
                                                                     linkedHashMap::new)),
                                            annotationClass);
    }

    
    Annotation[] getDeclaredAnnotations();
}

(1)isAnnotationPresent方法

default boolean isAnnotationPresent(Class annotationClass) {
        return getAnnotation(annotationClass) != null;
    }

如果指定类型的注解出现在当前元素上,则放回true,否则将返回false;注意defalut关键字,使得接口中的方法可以有一些默认的实现。

(2)getAnnotation方法:

 T getAnnotation(Class annotationClass);

如果在当前元素上存在参数所指定类型(annotationClass)的注解,则返回对应的注解,否则将返回null。

(3)getAnnotations方法

Annotation[] getAnnotations();

用于获取这个元素上的所有注解,并以数组形式放回。如果该元素上没有注解,那么将返回一个长度为0的数组。

调用该方法获取到的数组可以自由地修改,并且不会对返回给其他调用者的数组产生影响。

(4)getAnnotationsByType方法

default  T[] getAnnotationsByType(Class annotationClass) {
         
         T[] result = getDeclaredAnnotationsByType(annotationClass);

         if (result.length == 0 && // Neither directly nor indirectly present
             this instanceof Class && // the element is a class
             AnnotationType.getInstance(annotationClass).isInherited()) { // Inheritable
             Class superClass = ((Class) this).getSuperclass();
             if (superClass != null) {
                 // Determine if the annotation is associated with the
                 // superclass
                 result = superClass.getAnnotationsByType(annotationClass);
             }
         }

         return result;
     }

获取与该元素相关联的注解。如果没有与此元素相关联的注解,则返回值是长度为0的数组。这个方法与getAnnotation(Class)的区别在于,该方法检测其参数是否为可重复的注解类型(也就是是否被@Repeatable),如果是,则尝试通过“looking through”容器注解来查找该类型的一个或多个注解。

(5)getDeclaredAnnotation方法

default  T getDeclaredAnnotation(Class annotationClass) {
         Objects.requireNonNull(annotationClass);
         // Loop over all directly-present annotations looking for a matching one
         for (Annotation annotation : getDeclaredAnnotations()) {
             if (annotationClass.equals(annotation.annotationType())) {
                 // More robust to do a dynamic cast at runtime instead
                 // of compile-time only.
                 return annotationClass.cast(annotation);
             }
         }
         return null;
     }

获取直接出现在这个元素上的注解。这种方法忽略了继承的注解。如果在此元素上没有直接存在的注解,则返回值是长度为0的数组。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/310223.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号