java8对注解提供了两点改进:
- 可重复的注解
- 可用于类型的注解
可重复的注解
先定义一个注解
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnno {
String value() default "";
}
此时在成员变量上定义两个注解会报错
@MyAnno("哈哈")
@MyAnno("heh")
public void name(){
}
报错内容:Duplicate annotation. The declaration of 'repeatAnnotation.MyAnno' does not have a valid java.lang.annotation.Repeatable annotation
如何定义重复注解?
-
先定义一个父容器容器
-
用MyAnno作为变量类型,声明一个数组
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE}) @Retention(RetentionPolicy.RUNTIME) public @interface MyAnnos{ MyAnno[] value(); }
-
然后把原来注解上加个新注解@Repeatable,入参父容器类对象
@Repeatable(value = MyAnnos.class) @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE}) @Retention(RetentionPolicy.RUNTIME) public @interface MyAnno { String value() default ""; }
-
此时就不报错了
@MyAnno("哈哈") @MyAnno("heh") public void name(){ }
-
获取注解内容
由于设置了@Retention(RetentionPolicy.RUNTIME),所以可以通过反射获取注解值
@Test public void test() throws NoSuchMethodException { Class<demo> clazz = demo.class; //获取目标类的Class对象 Method name = clazz.getMethod("name"); MyAnno[] annos = name.getAnnotationsByType(MyAnno.class); for (MyAnno anno : annos) { System.out.println("anno = " + anno.value()); } } /* 结果: anno = 哈哈 anno = heh */
类型的注解
-
多了一个 TYPE_PARAMETER
@Repeatable(value = MyAnnos.class)
@Target({
TYPE, FIELD, METHOD, PARAMETER,
CONSTRUCTOR, LOCAL_VARIABLE,TYPE_PARAMETER}
)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnno {
String value() default "";
}