JavaSE進(jìn)階

2、類型注解

JDK1.8之后,關(guān)于元注解@Target的參數(shù)類型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開始,注解可以應(yīng)用在任何地方。

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的程序中做強(qiáng)類型檢查。配合第三方插件工具Checker Framework(使用Checker Framework可以找到類型注解出現(xiàn)的地方并檢查),可以在編譯的時候檢測出runtime error(eg:UnsupportedOperationException; NumberFormatException;NullPointerException異常等都是runtime error),以提高代碼質(zhì)量。這就是類型注解的作用。

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)入源代碼目錄 ??通過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錯誤。