java中@Repeatable的理解

@Repeatable是jdk8中新增的注解,使用如Spring中的@ComponentScan注解。在没有@Repeatable注解的的注解中,在同一个地方使用相同的注解会报错,有了此元注解注解的注解,就可以在同一个地方使用相同的注解。其官方文档如下

The annotation type {@code java.lang.annotation.Repeatable} is used to indicate that the annotation type whose declaration it (meta-)annotates is repeatable. The value of @Repeatable indicates the containing annotation type for the repeatable annotation type.
@Repeatable 注解是用于声明其它类型注解的元注解,来表示这个声明的注解是可重复的。@Repeatable的值是另一个注解,其可以通过这个另一个注解的值来包含这个可重复的注解。

示例

Value注解:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(Values.class)
public @interface Value {
    String value() default "value";
}

Values注解:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Values {
    Value[] value();
}

其中,@Value注解上的元注解@Repeatable中的值,使用了@Values注解,@Values注解中包含的值类型是一个@Value注解的数组!
这就解释了官方文档中@Repeatable中值的使用。

测试

注解使用方法

public class AnnotationClass {

    @Value("hello")
    @Value("world")
    public void test(String var1, String var2) {
        System.out.println(var1 + " " + var2);
    }
}

测试用例

// 获取使用`@Value`注解的`test`方法,并打印这个方法上的注解长度和信息
    @Test
    public void testValue() {
        Method[] methods = AnnotationClass.class.getMethods();
        for (Method method : methods){
            if (method.getName().equals("test")) {
                Annotation[] annotations = method.getDeclaredAnnotations();
                System.out.println(annotations.length);
                System.out.println(method.getName() + " = " + Arrays.toString(annotations));
            }
        }
    }

因为test方法上使用了两个@Value注解,所以猜测打印注解长度为2,然后打印详情,可是结果并不同。

1
test = [@com.example.annotations.Values(value=[@com.example.annotations.Value(value=hello), @com.example.annotations.Value(value=world)])]

结果显示,test方法上的注解长度为 1 , 且打印信息为@Values注解,它的值包含了使用的两个注解。
因此可知在jdk8中,相同注解只是以集合的方式进行了保存,原理并没有变化。

注意事项

一些约束

  • @Repeatable 所声明的注解,其元注解@Target的使用范围要比@Repeatable的值声明的注解中的@Target的范围要大或相同,否则编译器错误,显示@Repeatable值所声明的注解的元注解@Target不是@Repeatable声明的注解的@Target的子集
// Value
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(Values.class)
public @interface Value {
    String value() default "value";
}

// Values
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Values {
    Value[] value();
}

错误提示信息:
java中@Repeatable的理解_第1张图片

  • @Repeatable注解声明的注解的元注解@Retention的周期要比@Repeatable的值指向的注解的@Retention得周期要小或相同。

周期长度为 SOURCE(源码) < CLASS (字节码) < RUNTIME(运行)

// Value 注意 @Retention的值
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(Values.class)
public @interface Value {
    String value() default "value";
}
// Values
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.CLASS)
public @interface Values {
    Value[] value();
}

java中@Repeatable的理解_第2张图片

你可能感兴趣的:(java中@Repeatable的理解)