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還有很多其他使用方式,只要是能獲取到註解,我們就可以根據指定的註解做指定的事情。

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章