原文链接:http://tutorials.jenkov.com/java-reflection/annotations.html
通过使用Java 反射我们可以在程序运行时访问与 Java classes 相关的 annotations 。
What are Java Annotations?
Annotations 是 Java 5的新特性。 Annotations 是一种可以插入到我们代码中的一种注释或者是(meta data)。这些 annotations 可以被预编译工具在编译期或者是通过 Java 反射在运行时被处理。下面是一个 class annotation 的例子:@MyAnnotation(name="someName", value = "Hello World") public class TheClass { }
在 TheClass 这个类的上方有一个注解 @MyAnnotation 。注解的定义很像接口的定义。下面是 MyAnnotation 这个注解的定义:
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface MyAnnotation { public String name(); public String value(); }
在 interface 前面的 @ 符号标识出 MyAnnotation 是一个注解。一旦我们定义了注解,我们就可以像上面的例子那样来使用注解。在注解的定义中,有两种指令, @Retention(RetentionPolicy.TUNTIME) 和 @Target(ElementType.Type) ,定义了怎样来使用注解。
@Retention(RetentionPolicy.RUNTIME) 意味着我们可以使用 Java 反射在程序运行时来访问它。如果我们不设置这个指令,这个注解将不会在程序运行时保留信息,因此我们也就不可能在程序运行时来访问它。
@Target(ElementType.TYPE) 意味着这个注解只能用在类型(最典型的就是类和接口)的上方。我们也可以定义用在方法和字段上方的注解,或者是我们可以省去 @Target 这
条指令,省去这条指令后,这个注解就可以用在类、方法和字段的上面。
在我的 (原文作者)Java Annotations tutorial 中有对 Java 注解更详细的解释。
Class annotations
我们可以在程序运行时访问一个类、方法、字段的注解,下面是访问类的注解的例子:
Class aClass = TheClass.class; Annotation[] annotations = aClass.getAnnotations(); for(Annotation annotation : annotations){ if(annotation instanceof MyAnnotation){ MyAnnotation myAnnotation = (MyAnnotation) annotation; System.out.println("name: " + myAnnotation.name()); System.out.println("value: " + myAnnotation.value()); } }我们也可以像这样来访问一个类的特定的一个注解:
Class aClass = TheClass.class; Annotation annotation = aClass.getAnnotation(MyAnnotation.class); if(annotation instanceof MyAnnotation){ MyAnnotation myAnnotation = (MyAnnotation) annotation; System.out.println("name: " + myAnnotation.name()); System.out.println("value: " + myAnnotation.value()); }
Method Annotations
下面是一个带有注解的方法:
public class TheClass { @MyAnnotation(name="someName", value = "Hello World") public void doSomething(){} }我们可以像这样来访问一个方法的注解:
Method method = ... //obtain method object Annotation[] annotations = method.getDeclaredAnnotations(); for(Annotation annotation : annotations){ if(annotation instanceof MyAnnotation){ MyAnnotation myAnnotation = (MyAnnotation) annotation; System.out.println("name: " + myAnnotation.name()); System.out.println("value: " + myAnnotation.value()); } }我们也可以像这样来访问一个方法的特定注解:
Method method = ... // obtain method object Annotation annotation = method.getAnnotation(MyAnnotation.class); if(annotation instanceof MyAnnotation){ MyAnnotation myAnnotation = (MyAnnotation) annotation; System.out.println("name: " + myAnnotation.name()); System.out.println("value: " + myAnnotation.value()); }
Parameter Annotations
也可以在方法参数的声明上加注解,下面是一个例子:
public class TheClass { public static void doSomethingElse( @MyAnnotation(name="aName", value="aValue") String parameter){ } }我们可以像这样,通过 Method 对象来访问参数的注解:
Method method = ... //obtain method object Annotation[][] parameterAnnotations = method.getParameterAnnotations(); Class[] parameterTypes = method.getParameterTypes(); int i=0; for(Annotation[] annotations : parameterAnnotations){ Class parameterType = parameterTypes[i++]; for(Annotation annotation : annotations){ if(annotation instanceof MyAnnotation){ MyAnnotation myAnnotation = (MyAnnotation) annotation; System.out.println("param: " + parameterType.getName()); System.out.println("name : " + myAnnotation.name()); System.out.println("value: " + myAnnotation.value()); } } }
注意:Method.getParameterAnnotations() 方法返回了一个二维的 Annotation 数组,为什么是二维呢?因为一个参数上可以加多个注解,一个方法可能有多个参数,所以就返回了一个二维数组,二维数组的每一个元素是一个一维数组,这个一维数组包括了一个参数的一个或多个注解。补充:在一个类、方法、字段、参数上都可以加多个注解。
Field Annotations
下面的这个例子是一个带有注解的字段:
public class TheClass { @MyAnnotation(name="someName", value = "Hello World") public String myField = null; }我们可以像这样来访问一个字段的注解:
Field field = ... //obtain field object Annotation[] annotations = field.getDeclaredAnnotations(); for(Annotation annotation : annotations){ if(annotation instanceof MyAnnotation){ MyAnnotation myAnnotation = (MyAnnotation) annotation; System.out.println("name: " + myAnnotation.name()); System.out.println("value: " + myAnnotation.value()); } }我们也可以像这样来访问一个特定字段的注解:
public class TheClass { public static void doSomethingElse( @MyAnnotation(name="aName", value="aValue") String parameter){ } }