add by zhj: 使用@Repeatable的注解,只有在定义时需要指定@Repeatable的参数,注解容器,即下面的Skills。在使用注解时,并不会用到注解容器。
所以我建议使Programmer类那种注解方法,更简洁,而不建议使用Waiter类那种注解方式。
原文作者:lvbinbin2yujie
原文链接:https://www.cnblogs.com/lvbinbin2yujie/p/10291602.html
查看@PropertySource注解时候,发现了@Repeatable,从来没见过的注解,学习了下;
首先介绍下@Repeatable注解: JDK1.8出现的,作用是解决一个类上不能标注重复的注解;
当你尝试在标注重复注解时候,IDE编译器就会提示:
@Repeatable相当于指向一个容器,这样就可以在注解的地方重复标注注解了;
简单的使用例子,方便自己理解:
定义这样一个场景,每个人有不同的技能,不同职业的人又有不同的技能;
定义一个注解代表拥有的技能;
import static java.lang.annotation.ElementType.*; import static java.lang.annotation.RetentionPolicy.*; @Documented @Retention(RUNTIME) //运行时注解 @Target(TYPE) //类上的注解 @Repeatable(Skills.class) public @interface Skill { String value() default ""; }
容器注解Skills
import static java.lang.annotation.ElementType.*; import static java.lang.annotation.RetentionPolicy.*; @Documented @Retention(RUNTIME) @Target(TYPE) public @interface Skills { Skill[] value(); }
定义这样一个人的接口
@Skill(value="吃饭") @Skill(value="睡觉") public interface Human { }
定义了两个人的具体实现,展示了Skills的两种不同使用方式;
@Skill("编程") @Skill("打游戏") public class Programmer implements Human{ } @Skills({@Skill("迎宾"),@Skill("上菜")}) public class Waiter implements Human { }
测试类:
public class Main { public static void main(String[] args) { Human man = new Programmer(); // Human man = new Waiter(); List<Class> classes = new ArrayList<>(); classes.addAll(Arrays.asList(man.getClass().getInterfaces())); classes.add(man.getClass()); for (Class<?> clazz : classes) { Skill[] skills = clazz.getAnnotationsByType(Skill.class); for (Skill skill : skills) { System.out.println("他会:" + skill.value()); } } } }