Java註解反射

程序元素上的註解是Java對象。允許訪問其註解的程序元素實現java.lang.reflect.AnnotatedElement接口。以下類實現了AnnotatedElement接口:
AnnotatedElement接口的方法用於訪問以下列出的對象類型的註解。

java.lang.Class
java.lang.reflect.Executable
java.lang.reflect.Constructor
java.lang.reflect.Field
java.lang.reflect.Method
java.lang.reflect.Parameter
java.lang.Package
java.lang.reflect.AccessibleObject

註解類型必須使用運行時的保留策略來保留元註解,以便在運行時訪問它。

示例 - 1

假設有一個Test類,並且想打印它的所有註解。參考以下代碼片段,它將打印Test類的類聲明上的所有註解:

import java.lang.annotation.Annotation;

@SuppressWarnings("unchecked")
@Deprecated
public class Main {

public static void main(String[] argv) {
// Get the class object reference
Class

c = Main.class;
// Get all annotations on the class declaration
Annotation[] allAnns = c.getAnnotations();
System.out.println("Annotation count: " + allAnns.length);

// Print all annotations
for (Annotation ann : allAnns) {
  System.out.println(ann);
}

}
}

執行上面的代碼得到如下結果 -

Annotation count: 1
@java.lang.Deprecated()

如上面的結果所示,Annotation接口的toString()方法返回註解的字符串表示形式。

實例-2

以下代碼顯示瞭如何獲取指定的註解,請參考以下代碼 -

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
@Documented
@interface Version {
int major();

int minor();
}
@Version(major=1,minor=2)
public class Main {
public static void main(String[] argv) {
Class

c = Main.class;

Version v = c.getAnnotation(Version.class);
if (v == null) {
  System.out.println("Version annotation is  not  present.");
} else {
  int major = v.major();
  int minor = v.minor();
  System.out.println("Version: major=" + major + ", minor=" + minor);
}

}
}

上面的代碼生成以下結果。

Version: major=1, minor=2

實例-3

以下代碼顯示瞭如何訪問方法的註解,請參考以下代碼 -

import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;

@Retention(RetentionPolicy.RUNTIME)
@interface Version {
int major();
int minor();
}

@Version(major = 1, minor = 0)
class AccessAnnotation {
@Version(major = 1, minor = 1)
public void testMethod1() {
}

@Version(major = 1, minor = 2)
@Deprecated
public void testMethod2() {
}
}

public class Main {
public static void main(String[] args) {
Class c = AccessAnnotation.class;
System.out.println("Annotations for class:" + c.getName());
printAnnotations(c);

System.out.println("Method annotations:");
Method\[\] m = c.getDeclaredMethods();
for (int i = 0; i < m.length; i++) {
  System.out.println("Annotations for method:" + m\[i\].getName());
  printAnnotations(m\[i\]);
}

}

public static void printAnnotations(AnnotatedElement programElement) {
Annotation[] annList = programElement.getAnnotations();
for (int i = 0; i < annList.length; i++) {
System.out.println(annList[i]);
if (annList[i] instanceof Version) {
Version v = (Version) annList[i];
int major = v.major();
int minor = v.minor();
System.out.println("Found Version annotation: " + "major =" + major
+ ", minor=" + minor);
}
}
}
}

上面的代碼生成以下結果。

Annotations for class:AccessAnnotation
@Version(major=1, minor=0)
Found Version annotation: major =1, minor=0
Method annotations:
Annotations for method:testMethod1
@Version(major=1, minor=1)
Found Version annotation: major =1, minor=1
Annotations for method:testMethod2
@Version(major=1, minor=2)
Found Version annotation: major =1, minor=2
@java.lang.Deprecated()

實例-4

以下代碼顯示瞭如何在運行時訪問可重複註解的實例,請參考以下代碼 -

import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
@interface LogHistory {
Log[] value();
}
@Repeatable(LogHistory.class)
@interface Log {
String date();
String comments();
}

@Log(date = "02/01/2018", comments = "A")
@Log(date = "01/22/2018", comments = "B")
public class Main {
public static void main(String[] args) {
Class

mainClass = Main.class;

Log\[\] annList = mainClass.getAnnotationsByType(Log.class);
for (Log log : annList) {
  System.out.println("Date=" + log.date() + ", Comments=" + log.comments());
}

Class<LogHistory> containingAnnClass = LogHistory.class;
LogHistory logs = mainClass.getAnnotation(containingAnnClass);

for (Log log : logs.value()) {
  System.out.println("Date=" + log.date() + ", Comments=" + log.comments());
}

}
}

上面的代碼生成以下結果。

Date=02/01/2018, Comments=A
Date=01/22/2018, Comments=B
Date=02/01/2018, Comments=A
Date=01/22/2018, Comments=B