JavaSE進(jìn)階
2、類(lèi)型注解
JDK1.8之后,關(guān)于元注解@Target的參數(shù)類(lèi)型ElementType枚舉值多了兩個(gè):
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開(kāi)始,注解可以應(yīng)用在任何地方。
ElementType.TYPE_PARAMETER 表示該注解能寫(xiě)在類(lèi)型變量的聲明語(yǔ)句中(eg:泛型聲明)。
ElementType.TYPE_USE 表示該注解能寫(xiě)在使用類(lèi)型的任何語(yǔ)句中。
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{ } |
類(lèi)型注解被用來(lái)支持在Java的程序中做強(qiáng)類(lèi)型檢查。配合第三方插件工具Checker Framework(使用Checker Framework可以找到類(lèi)型注解出現(xiàn)的地方并檢查),可以在編譯的時(shí)候檢測(cè)出runtime error(eg:UnsupportedOperationException; NumberFormatException;NullPointerException異常等都是runtime error),以提高代碼質(zhì)量。這就是類(lèi)型注解的作用。
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()); } } |
進(jìn)入源代碼目錄 ??通過(guò)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 有個(gè)向下兼容的解決方案,就是將類(lèi)型注解@NonNull 用/**/注釋起來(lái)。
這樣javac編譯器就會(huì)忽略掉注釋塊,但用checker framework里面的javac編譯器同樣能夠檢測(cè)出@NonNull錯(cuò)誤。