在java8之前,如果需要在同一个元素上使用多个相同类型的注解,需要借助注解“容器”来实现.
例如:
@TestRepeatables({
@TestRepeatable(name = "test1"),
@TestRepeatable(name = "test2")}
)
public class TestAnnotation1 {
}
java8开始引入了新特性:重复注解
在我们定义需要重复的注解时,使用@Repeatable注解表示对应的注解是可重复的。
在上面的例子中我们可以这样写了:
@TestRepeatable(name = "test1")
@TestRepeatable(name = "test2")
public class TestAnnotation {
}
自定义注解代码:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Inherited
@Repeatable(TestRepeatables.class)
public @interface TestRepeatable {
String name();
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Inherited
public @interface TestRepeatables {
TestRepeatable[] value();
}
接下来我们写个测试类验证下
代码如下:
public class Test {
public static void main(String[] args) {
TestRepeatable testRepeatable = TestAnnotation.class.getAnnotation(TestRepeatable.class);
System.out.println(testRepeatable.name());
}
}
运行发现报空指针异常
我们看下getAnnotation方法源码的介绍:
明明代码上面使用的就是@TestRepeatable注解,怎么获取不到呢
我们看下编译后的文件如下:
可以看到编译后的TestAnnotation.class文件上使用的是@TestRepeatables注解,其实可以看到@TestRepeatable注解java8底层帮我们换成了java8之前的那种写法,也就是使用@Repeatable语法糖,底层会帮开发者处理这些事情。
更改测试代码如下:
public class Test {
public static void main(String[] args) {
TestRepeatables testRepeatable = TestAnnotation.class.getAnnotation(TestRepeatables.class);
TestRepeatable[] value = testRepeatable.value();
Arrays.stream(value).forEach(v->{
System.out.println(v.name());
});
}
}
运行结果: