(1)可以进行重复注解

自从Java 5引入了注解机制,这一特性就变得非常流行并且广为使用。然而,使用注解的一个限制是相同的注解在同一位置只能声明一次,不能声明多次。Java 8打破了这条规则,引入了重复注解机制,这样相同的注解可以在同一地方声明多次。

重复注解机制本身必须用@Repeatable注解。事实上,这并不是语言层面上的改变,更多的是编译器的技巧,底层的原理保持不变。

(2)扩展注解的支持

Java 8扩展了注解的上下文。现在几乎可以为任何东西添加注解:局部变量、泛型类、父类与接口的实现,就连方法的异常也能添加注解。

标注在类,方法等上面的注解可以重复出现,如下图:

java 注册重复 java可重复注解_java 添加注解

1.可重复注解

java 注册重复 java可重复注解_Java_02

JDK1.8之后,可读性更好

java 注册重复 java可重复注解_java_03

2.类型注解

JDK1.8之后,关于元注解@Target的参数类型ElementType枚举值多了两个:

java 注册重复 java可重复注解_java 注册重复_04

java 注册重复 java可重复注解_Java_05

在java 8之前,注解只能是在声明的地方所使用,java8开始,注解可以应用在任何地方。

ElementType.TYPE_PARAMETER 表示该注解能写在类型变量的声明语句中(eg:泛型声明)。

ElementType.TYPE_USE 表示该注解能写在使用类型的任何语句中。

java 注册重复 java可重复注解_java 添加注解_06

java 注册重复 java可重复注解_java 注册重复_07

类型注解被用来支持在Java的程序中做强类型检查。配合第三方插件工具Checker Framework(使用Checker Framework可以找到类型注解出现的地方并检查),可以在编译的时候检测出runtime error(eg:UnsupportedOperationException;NumberFormatException;NullPointerException异常等都是runtime error),以提高代码质量。这就是类型注解的作用。

java 注册重复 java可重复注解_Java_08

java 注册重复 java可重复注解_jar_09

进入源代码目录   通过javac编译  -processor 后面接注释处理流程

javac  -processor org.checkerframework.checker.nullness.NullnessChecker TestChecker.java

java 注册重复 java可重复注解_java 注册重复_10

警告处理

javac -Xbootclasspath/p:D:\software\eclipse\checker-framework-2.1.13\checker\dist\jdk8.jar -processor org.checkerframework.checker.nullness.NullnessChecker TestChecker.java

要配置classpath=.;%JAVA_HOME%/lib/dt.jar;%JAVA_HOME%/lib/tools.jar;D:\software\eclipse\checker-framework-2.1.13\checker\dist\checker.jar;D:\software\eclipse\checker-framework-2.1.13\checker\dist\checker-qual.jar;

注意java 5,6,7版本是不支持注解@NonNull,但checker framework 有个向下兼容的解决方案,就是将类型注解@NonNull 用/**/注释起来。

这样javac编译器就会忽略掉注释块,但用checker framework里面的javac编译器同样能够检测出@NonNull错误。

但是如果你直接在方法等上面注多个相同的注解,程序还是会报错,错误信息提示注解MyAnnotation没有被一个Repeatable注解修饰,而Repeatable注解里面传入的参数必须也是一个注解,这个注解所包含的值必须有一个要重复注解的这个注解类型的数组。我们同样可以和以前一样通过反射得到注解的值,如下代码:

java 注册重复 java可重复注解_java_11

结果如图:

java 注册重复 java可重复注解_jar_12