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<Main> 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<Main> 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<AccessAnnotation> 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<Main> 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

上一篇:Java标准注解

下一篇:没有了

关注微信小程序
程序员编程王-随时随地学编程

扫描二维码
程序员编程王

扫一扫关注最新编程教程