AnnotatedElement作用域范围

发布时间 2023-11-24 10:45:24作者: ccblblog

1、直接存在

直接被某个注解标注在类上的形式,称为直接存在,@testAnnotation是直接存在Test类上

@testAnnotation
public class Test{}

2、间接存在

使用@Repeatable注解标记一个可重复注解时,将这个可重复注解标注在元素之上时,这个可重复注解就是间接存在于元素之上的,如果标注的这个可重复注解只有一个,不能称为间接存在,至少需要被两个相同的可重复注解标注才能成为间接存在。

import java.lang.annotation.*;

@Test.testAnnotation(1)
@Test.testAnnotation(2)
@SuppressWarnings("all")
public class Test {
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface RepeatableAnnotation {
        testAnnotation[] value();
    }
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Repeatable(RepeatableAnnotation.class)
    @Documented
    public @interface testAnnotation {
        int value();
    }
}

使用javap反编译Test.class生成的文件,可以看到原先在Test类上标注过testAnnotation,但是根据生成的字节码反编译的java文件中全部转化为了RepeatableAnnotation,说明是使用testAnnotation是间接存在的

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Test.RepeatableAnnotation({@Test.testAnnotation(1), @Test.testAnnotation(2)})
public class Test {
    public Test() {
    }
    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Repeatable(RepeatableAnnotation.class)
    @Documented
    public @interface testAnnotation {
        int value();
    }

    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface RepeatableAnnotation {
        testAnnotation[] value();
    }
}

3、存在

满足以下两点的称为存在

  1. 直接标注在元素上的注解(直接存在)
  2. 元素所有父类中找到一个直接标注的注解(所有父类直接存在)

类A继承类B类B直接标注testAnnotation注解,所以testAnnotation是直接存在在类B上,因为testAnnotation只在类B上标注过一次,所以是直接存在,如果标注两次及以上,则成为间接存在。所以类A上存在testAnnotationRepeatableAnnotation注解,满足条件2

import java.lang.annotation.*;

public class Test {
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Inherited
    @Documented
    public @interface RepeatableAnnotation {
        testAnnotation[] value();
    }
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Repeatable(RepeatableAnnotation.class)
    @Inherited
    @Documented
    public @interface testAnnotation {
        int value();
    }
    @testAnnotation(1)
    @testAnnotation(2)
    static class A extends B {
    }
    @testAnnotation(3)
    static class B{
    }
}

3、关联

满足以下三点的称为关联

  1. 直接标注在元素上的注解(直接存在)
  2. 间接标注在元素上的注解(间接存在)
  3. 元素所有父类中找到一个直接或间接标注的注解(所有父类直接存在或间接存在)

总结

AnnotatedElement中的方法都是基于注解以何种形式存在于对象上获取元素上的注解的, 下表总结了此接口中各方法获取元素注解的范围:

image

本文大部分参考了 https://www.zyc.red/Java/Reflection/AnnotatedElement/ 以上加了一些个人的理解,仅做学习使用