Java 8对注解处理提供了两点改进:可重复的注解及可用于类型的注解。此外,反射也得到了加强,在Java8中能够得到方法参数的名称。这会简化标注在方法参数上的注解。
1、可重复注解
package com.atguigu.anno;
import java.lang.annotation.ElementType; import java.lang.annotation.Target;
public class TestOldAnnotation {
@RoleAnnotations({@RoleAnnotation(role=”admin”),@RoleAnnotation(role=”manager”),@RoleAnnotation(role=”saler”)}) public void add(){ }
} @Target(ElementType.METHOD) @interface RoleAnnotation{ String role() default “admin”; }
//表示target是所有 @interface RoleAnnotations{ RoleAnnotation[] value(); } |
JDK1.8之后,可读性更好
package com.atguigu.anno;
import java.lang.annotation.ElementType; import java.lang.annotation.Repeatable; import java.lang.annotation.Target;
public class TestNewAnnotation {
@LimitAnnotation(role=”admin”) @LimitAnnotation(role=”manager”) @LimitAnnotation(role=”saler”) public void test(){
} }
@Target(ElementType.METHOD) 此处的target必须与LimitAnnotation一致 @interface LimitAnnotations{ LimitAnnotation[] value(); }
@Repeatable(LimitAnnotations.class) @Target(ElementType.METHOD) @interface LimitAnnotation{ String role() default “admin”; } |
2、类型注解
JDK1.8之后,关于元注解@Target的参数类型ElementType枚举值多了两个:
public enum ElementType { /** Class, interface (including annotation type), or enum declaration */ TYPE,
/** Field declaration (includes enum constants) */ FIELD,
/** Method declaration */ METHOD,
/** Formal parameter declaration */ PARAMETER,
/** Constructor declaration */ CONSTRUCTOR,
/** Local variable declaration */ LOCAL_VARIABLE,
/** Annotation type declaration */ ANNOTATION_TYPE,
/** Package declaration */ PACKAGE,
/** * Type parameter declaration * * @since 1.8 */ TYPE_PARAMETER,
/** * Use of a type * * @since 1.8 */ TYPE_USE } |
在java 8之前,注解只能是在声明的地方所使用,java8开始,注解可以应用在任何地方。
ElementType.TYPE_PARAMETER 表示该注解能写在类型变量的声明语句中(eg:泛型声明)。
ElementType.TYPE_USE 表示该注解能写在使用类型的任何语句中。
package com.atguigu.anno;
import java.lang.annotation.ElementType; import java.lang.annotation.Target;
public class TestTypeDefine<@TypeDefine() U> {
private U u;
public <@TypeDefine() T> void test(T t){
}
} @Target({ElementType.TYPE_PARAMETER}) @interface TypeDefine{ } |
package com.atguigu.anno;
import java.lang.annotation.ElementType; import java.lang.annotation.Target;
@MyAnnotation public class TestAnnotation<U>{ @MyAnnotation private String name;
public static void main(String[] args) { TestAnnotation <@MyAnnotation String> t = null; int a = (@MyAnnotation int)2L; @MyAnnotation int b = 10; }
public static <@MyAnnotation T> void method(T t){
}
public static void test(@MyAnnotation String arg)throws @MyAnnotation Exception{
}
}
@Target(ElementType.TYPE_USE) @interface MyAnnotation{ } |
类型注解被用来支持在Java的程序中做强类型检查。配合第三方插件工具Checker Framework(使用Checker Framework可以找到类型注解出现的地方并检查),可以在编译的时候检测出runtime error(eg:UnsupportedOperationException; NumberFormatException;NullPointerException异常等都是runtime error),以提高代码质量。这就是类型注解的作用。
package checker;
import org.checkerframework.checker.nullness.qual.NonNull;
public class TestChecker { public static void main(String[] args) { Object obj = null; printNonNullToString(obj); }
public static void printNonNullToString(@NonNull Object object) { System.out.println(object.toString()); }
} |
|
进入源代码目录 通过javac编译 -processor 后面接注释处理流程 |
javac -processor org.checkerframework.checker.nullness.NullnessChecker TestChecker.java |
![]() |
警告处理 |
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错误。
上一篇: WEB前端与JAVA的区别
下一篇: 尚硅谷Java培训之枚举