Java反射-注释
使用Java Reflection,我们可以在运行时访问添加到Java类的注释。
什么是Java注释(Java Annotations)?
注释是Java 5的一项新函数。注释是一种注释或者元数据,我们可以在Java代码中插入。然后可以在编译时通过预编译器工具处理这些批注,或者在运行时通过Java Reflection处理这些批注。这是一个类注释的示例:
@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"前面的" @"将其标记为注释。定义注释后,便可以在代码中使用它,如前面的示例所示。
注释定义中的两个伪指令,@ Retention(RetentionPolicy.RUNTIME)和@Target(ElementType.TYPE),指定了注释的使用方式。
@Retention(RetentionPolicy.RUNTIME)意味着可以在运行时通过反射来访问注释。如果我们未设置此指令,则注释将不会在运行时保留,因此无法通过反射使用。
@Target(ElementType.TYPE)意味着注释只能在类型(通常是类和接口)的顶部使用。我们还可以指定METHOD
或者FIELD
,或者可以将目标全部排除在外,以便注释可用于类,方法和字段。
Java批注在我的Java批注教程中有更详细的说明。
类注释
我们可以在运行时访问类,方法或者字段的注释。这是访问类注释的示例:
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()); }
方法注释
这是带有注释的方法的示例:
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()); }
参数注释
也可以在方法参数声明中添加注释。看起来是这样的:
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数组,其中包含每个方法参数的注释数组。
栏位注解
这是带有注释的字段的示例:
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()); } }
我们还可以像这样访问特定的字段批注:
Field field = ... // obtain method object Annotation annotation = field.getAnnotation(MyAnnotation.class); if(annotation instanceof MyAnnotation){ MyAnnotation myAnnotation = (MyAnnotation) annotation; System.out.println("name: " + myAnnotation.name()); System.out.println("value: " + myAnnotation.value()); }