@Target注解標記另外的注解用於限制此注解可以應用哪種Java元素類型。
先看Java SE 8中@Target是如何聲明的:
package java.lang.annotation; 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.lang.annotation.ElementType此枚舉類聲明了有哪些Java元素類型:
java.lang.annotation.ElementType.TYPE:類、接口(包括注解類型)和枚舉的聲明
java.lang.annotation.ElementType.FIELD:字段聲明(包括枚舉常量)
java.lang.annotation.ElementType.METHOD:方法聲明
java.lang.annotation.ElementType.PARAMETER:參數聲明
java.lang.annotation.ElementType.CONSTRUCTOR:構造函數聲明
java.lang.annotation.ElementType.LOCAL_VARIABLE:本地變量聲明
java.lang.annotation.ElementType.ANNOTATION_TYPE:注解類型聲明
java.lang.annotation.ElementType.PACKAGE:包聲明
java.lang.annotation.ElementType.TYPE_PARAMETER:類型參數聲明,JavaSE8引進,可以應用於類的泛型聲明之處
java.lang.annotation.ElementType.TYPE_USE:JavaSE8引進,此類型包括類型聲明和類型參數聲明,是為了方便設計者進行類型檢查,例如,如果使用@Target(ElementType.TYPE_USE)對@NonNull進行標記,則類型檢查器可以將@NonNull class C {...} C類的所有變量都視為非null
注意:如果一個注解沒有指定@Target注解,則此注解可以用於除了TYPE_PARAMETER和TYPE_USE以外的任何地方。
以下我們看看ElementType.TYPE_PARAMETER和ElementType.TYPE_USE的使用示例,對於其他的ElementType注解元素,看其說明就知道怎么用了:
聲明由ElementType.TYPE_PARAMETER標記的@NotEmpty注解:
package org.springmorning.demo.javabase.annotation.meta; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @author 春晨 * Copyright ©2019 春晨 https://www.cnblogs.com/springmorning/p/10264624.html */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE_PARAMETER) public @interface NotEmpty { }
聲明由ElementType.TYPE_USE標記的@NotEmpty注解:
package org.springmorning.demo.javabase.annotation.meta; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @author 春晨 * Copyright ©2019 春晨 https://www.cnblogs.com/springmorning/p/10264624.html */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE_USE) public @interface NotNull { }
以下示例代碼說明了這兩種Target注解元素的使用區別,ElementType.TYPE_USE包含了ElementType.TYPE和ElementType.TYPE_PARAMETER
package org.springmorning.demo.javabase.annotation.meta; /** * @author 春晨 * Copyright ©2019 春晨 https://www.cnblogs.com/springmorning/p/10264624.html */ import java.util.ArrayList; //泛型類型聲明時,使用TYPE_USE類型,編譯通過 class A <@NotNull TT>{} //泛型類型聲明時,使用使用TYPE_PARAMETER類型,編譯通過 public class TypeParameterAndTypeUseAnnotation<@NotEmpty T>{ //使用TYPE_PARAMETER類型,會編譯不通過 // public @NotEmpty T test(@NotEmpty T a){ // new ArrayList<@NotEmpty String>(); // return a; // } //使用TYPE_USE類型,編譯通過 public @NotNull T test(@NotNull T a){ new ArrayList<@NotNull String>(); return a; } }
下節繼續
下節將給大家講解元注解@Retention的使用。