一、为什么要用重复注解
在Java 8之前我们在方法或类上同种注解只能声明一次,在一些业务条件下光靠注解就无法实现需求。
例如我们定义的@RequestMapping注解和@Student的注解:
public class TestJava8 {
@RequestMapping("/test")
@RequestMapping(value = "/test2",method = Method.POST)
public void test(){
}
}
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface RequestMapping{
String value();
Method method() default Method.GET;
}
enum Method{POST,GET}
或者简单一点
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Xc9ZPWL0-1653903175625)(//img-blog.csdn.net/20180318015243211?watermark/2/text/Ly9ibG9nLmNzZG4ubmV0L3FxXzM3NDkzODg4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)]
两种都会报错,或许你可以通过改变数组设计方式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gI2BpUMF-1653903175626)(//img-blog.csdn.net/20180318015736589?watermark/2/text/Ly9ibG9nLmNzZG4ubmV0L3FxXzM3NDkzODg4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)]
虽然编译期不报错了,你有没发现这种编程方式十分的不优雅,不管是使用者在用该注解时,还是设计者在通过反射获取值时都十分的不方便。
二、重复注解的引入
2.1、再定义一个@StudentList注解
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface StudentList{
Student[] value();
}
2.2、在@Student注解上添加@Repeatable注解
Java 8中提供了一个注解@Repeatable
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(StudentList.class)
@interface Student{
String name();
int age();
}
2.3 两种写法
//写法一
@Student(age = 17, name = "张三")
@Student(age = 18, name = "李四")
public void test(){
}
//写法二
@StudentList({@Student(age = 17, name = "张三"),@Student(age = 18, name = "李四")})
public void test1() {
}
这时编译期正常
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-097qqcbm-1653903175627)(//img-blog.csdn.net/20180318021810114?watermark/2/text/Ly9ibG9nLmNzZG4ubmV0L3FxXzM3NDkzODg4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)]
2.4、获取值
两个方法在反射获取值时,你需要把@Student当成@StudentList
//获取值
Class<?> clazz = TestJava8.class;
Method method = clazz.getMethod("test");
StudentList studentList = method.getAnnotation(StudentList.class);
Student[] values = studentList.value();
for (Student stu : values) {
System.out.println(stu.name());
System.out.println(stu.age());
}