Java Reflection - Annotations

原文链接: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){
  }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值