博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
2、Annotation的实现
阅读量:4036 次
发布时间:2019-05-24

本文共 2810 字,大约阅读时间需要 9 分钟。

说到Annotation的实现,先来看个示例:

定义自定义注解:

@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)public @ interface MyAnnotation {    int value() default 0;}

测试自定义注解:

@MyAnnotation(value=1)public class TestAnnotation {    public static void main(String[] args) throws Exception {        MyAnnotation myAnnotation = TestAnnotation.class.getAnnotation(MyAnnotation.class);        System.out.println(myAnnotation.value());    }}

万物皆对象,注解类也是个对象,关键在于怎么去实例化它。 从测试类中可以看出通过Class类提供的getAnnotation()方法可以获取到指定注解类对象。所以关键在于getAnnotation的方法实现。

没啥可说的,跟代码吧。

通过这里可以看出是通过一个get方法取出来的,所以猜测annotations一定是个集合类的容器,key是class,value是注解对象。

从这里可以看出,annotations这个容器是AnnotationData对象的属性,AnnotationData是Class的内部静态类。所以annotationData()方法一定是获取到AnnotationData对象的方法。

从这段代码可以看出annotationData是Annotation的缓存数据。

annotationData()方法里面唯一创建AnnotationData的就是
AnnotationData newAnnotationData = createAnnotationData(classRedefinedCount);

我们看下createAnnotationData这个方法

private AnnotationData createAnnotationData(int classRedefinedCount) {        Map
, Annotation> declaredAnnotations = AnnotationParser.parseAnnotations(getRawAnnotations(), getConstantPool(), this); Class
superClass = getSuperclass(); Map
, Annotation> annotations = null; if (superClass != null) { Map
, Annotation> superAnnotations = superClass.annotationData().annotations; for (Map.Entry
, Annotation> e : superAnnotations.entrySet()) { Class
annotationClass = e.getKey(); if (AnnotationType.getInstance(annotationClass).isInherited()) { if (annotations == null) { // lazy construction annotations = new LinkedHashMap<>((Math.max( declaredAnnotations.size(), Math.min(12, declaredAnnotations.size() + superAnnotations.size()) ) * 4 + 2) / 3 ); } annotations.put(annotationClass, e.getValue()); } } } if (annotations == null) { // no inherited annotations -> share the Map with declaredAnnotations annotations = declaredAnnotations; } else { // at least one inherited annotation -> declared may override inherited annotations.putAll(declaredAnnotations); } return new AnnotationData(annotations, declaredAnnotations, classRedefinedCount); }

在这个方法里面,最关键的是获取declaredAnnotations, 它是一个Map对象,key是继承了Annotation接口的类,value是Annotation对象。 getRawAnnotations()   getConstantPool()这两个方法都是native方法。所以一定是这里生成了我们定义的Annotation对象,然后转化到了map集合中。

我们可以看到这个对象是一个Proxy1的对象,即通过代理方式生成的。

Annotation还有很多其他使用方式,只要是能获取到注解,我们就可以根据指定的注解做指定的事情。

 

 

 

 

转载地址:http://wqcdi.baihongyu.com/

你可能感兴趣的文章
利用清华镜像站解决pip超时问题
查看>>
[leetcode BY python]1两数之和
查看>>
微信小程序开发全线记录
查看>>
Centos import torchvision 出现 No module named ‘_lzma‘
查看>>
PTA:一元多项式的加乘运算
查看>>
CCF 分蛋糕
查看>>
解决python2.7中UnicodeEncodeError
查看>>
小谈python 输出
查看>>
Django objects.all()、objects.get()与objects.filter()之间的区别介绍
查看>>
python:如何将excel文件转化成CSV格式
查看>>
Django 的Error: [Errno 10013]错误
查看>>
机器学习实战之决策树(一)
查看>>
机器学习实战之决策树二
查看>>
[LeetCode By Python]7 Reverse Integer
查看>>
[leetCode By Python] 14. Longest Common Prefix
查看>>
[leetCode By Python]111. Minimum Depth of Binary Tree
查看>>
[LeetCode By Python]118. Pascal's Triangle
查看>>
[LeetCode By Python]121. Best Time to Buy and Sell Stock
查看>>
[LeetCode By Python]122. Best Time to Buy and Sell Stock II
查看>>
[LeetCode By Python]125. Valid Palindrome
查看>>