2、Annotation的实现

说到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<Class<? extends Annotation>, Annotation> declaredAnnotations =
            AnnotationParser.parseAnnotations(getRawAnnotations(), getConstantPool(), this);
        Class<?> superClass = getSuperclass();
        Map<Class<? extends Annotation>, Annotation> annotations = null;
        if (superClass != null) {
            Map<Class<? extends Annotation>, Annotation> superAnnotations =
                superClass.annotationData().annotations;
            for (Map.Entry<Class<? extends Annotation>, Annotation> e : superAnnotations.entrySet()) {
                Class<? extends Annotation> 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还有很多其他使用方式,只要是能获取到注解,我们就可以根据指定的注解做指定的事情。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值