5. Annotation(註解)java
Annotation是一種元數據(metadata),即「Information about information」,在源代碼中標記。數組
註解使用類Javadoc的語法,@ANNOTATION_NAME(參數),參數爲KEY=VALUE的形式。ide
5.1 內置註解類型this
內置的註解類型位於java.lang包中,不需導入,開箱即用。spa
5.1.1. Overridecode
標明方法覆寫了基類的方法。此註解爲一種標識註解,無參數。orm
JDK源碼以下:繼承
@Target(ElementType.METHOD) @Retention(RetentionPolicy.SOURCE) public @interface Override { }
5.1.2. Deprecated接口
代表不推薦使用。此註解爲一種標識註解,無參數。ip
JDK源碼以下:
@Documented @Retention(RetentionPolicy.RUNTIME) public @interface Deprecated { }
5.1.3. SuppressWarnings
關閉類、方法、屬性等的指定編譯器警告。此註解接收一個String[]類型的參數。
JDK源碼以下:
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE}) @Retention(RetentionPolicy.SOURCE) public @interface SuppressWarnings { String[] value(); }
SuppressWarnings註解用法示例:
@SuppressWarnings(value={"unchecked"}) public void nonGenericsMethod( ) { List list = new ArrayList( ); list.add("foo"); }
5.2 註解的註解
註解的註解即描述元數據的元數據,如上述註解的JDK源代碼中的註解。
5.2.1 Target
標明註解能夠做用的目標範圍。
JDK源碼以下:
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Target { ElementType[] value(); }
其中ElementType的取值爲:
TYPE:類、接口(包含註解)、枚舉類型
FIELD:屬性(包含枚舉類型的值)
METHOD:方法
PARAMETER:方法參數
CONSTRUCTOR:構造方法
LOCAL_VARIABLE:局部變量
ANNOTATION_TYPE:註解類型
JDK源代碼:
public enum ElementType { /** Class, interface (including annotation type), or enum declaration */ TYPE, /** Field declaration (includes enum constants) */ FIELD, /** Method declaration */ METHOD, /** Parameter declaration */ PARAMETER, /** Constructor declaration */ CONSTRUCTOR, /** Local variable declaration */ LOCAL_VARIABLE, /** Annotation type declaration */ ANNOTATION_TYPE, /** Package declaration */ PACKAGE }
5.2.2 Retention
標明註解能夠保持的範圍。
JDK源碼以下:@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Retention { RetentionPolicy value(); }
其中RetentionPolicy的取值爲:
public enum RetentionPolicy { /** * Annotations are to be discarded by the compiler. */ SOURCE, /** * Annotations are to be recorded in the class file by the compiler * but need not be retained by the VM at run time. This is the default * behavior. */ CLASS, /** * Annotations are to be recorded in the class file by the compiler and * retained by the VM at run time, so they may be read reflectively. * * @see java.lang.reflect.AnnotatedElement */ RUNTIME }
5.2.3 Documented
標明Javadoc文檔中需包含此註解內容。
JDK源碼以下:
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Documented { }
注:Documented註解的使用要求註解的RetentionPolicy的設置爲RUNTIME
5.2.4 Inherited
標明做用於class上的註解是被自動繼承的註解。
JDK源碼以下:@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Inherited { }
注意:
1. Inherited註解的使用要求註解的RetentionPolicy的設置爲RUNTIME
2. 接口上的註解即便是標明瞭@Inherited的註解,也不會被繼承
3. 基類方法上的註解若是標明瞭@Inherited則會被繼承,但在被子類覆寫後也會丟失註解信息
5.3 自定義註解類型
註解類型本質上是一種Java的接口,但使用@interface關鍵字進行聲明。
示例:
public @interface Todo { public enum Severity {CRITICAL, IMPORTANT, TRIVIAL, DOCUMENTATION}; String description(); String assignedTo(); }
使用示例:
@Todo( severity=Todo.Severity.CRITICAL, description="Figure out the amount of order", assignedTo="Tom" ) public void calculate() { // Need to finish this method later }
5.5 新增的反射API
在java.lang.reflect包中新增了AnnotatedElement接口,JDK源碼以下:
public interface AnnotatedElement { boolean isAnnotationPresent(Class<? extends Annotation> annotationClass); <T extends Annotation> T getAnnotation(Class<T> annotationClass); Annotation[] getAnnotations(); Annotation[] getDeclaredAnnotations(); }
reflect包中的相關類如Class等都實現了此接口。
注:反射要求註解的RetentionPolicy的設置爲RUNTIME