Better

业精于勤荒于嬉

Java反射8-注解

Better's Avatar 2017-02-26 Java译文

  1. 1. 什么是Java注解
  2. 2. 类的注解
  3. 3. 方法的注解
  4. 4. 参数的注解
  5. 5. 成员变量的注解
  • What are Java Annotations?
  • Class Annotations
  • Method Annotations
  • Parameter Annotations
  • Field Annotations

使用Java反射你可以在程序运行时获取到注解。

什么是Java注解

注解是Java5开始新增的一个功能。注解是一种可以在Java代码插入的注释已经元素。在预编译工具编译的时候或者通过Java反射这些注解可以被获取到的。例子如下:

1
2
3
@MyAnnotation(name="someName",  value = "Hello World")
public class TheClass {
}

TheClass类有一个注解@MyAnnoation是卸载顶部的。注解想接口一样来定义。比如:

1
2
3
4
5
6
7
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)

public @interface MyAnnotation {
public String name();
public String value();
}

在接口类名前面添加@符号就申明了一个注解。一旦你定义了注解,你就可以使用它比如在上文例子中那样。
在注解的最顶部申明的@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)说明了这个注解是怎么使用的。
@Retention(RetentionPolicy.RUNTIME)说明了注解可以通过Java反射来获取。如果你不设置这句你就不能通过Java反射来获取这个注解。
@Target(ElementType.TYPE)说明了注解只能在类或者接口的顶部使用。你也可以指定Method或者FIELD,或者你不申明这句让注解在所有的地方都可用。
更多关于注解参考

类的注解

在程序运行时你可以获取到类,方法或者成员变量域的注解。比如获取的所有类的注解对象:

1
2
3
4
5
6
7
8
9
10
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());
}
}

你可以获取指定的注解对象:

1
2
3
4
5
6
7
8
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());
}

方法的注解

方法带有注解:

1
2
3
4
public class TheClass {
@MyAnnotation(name="someName", value = "Hello World")
public void doSomething(){}
}

获取例子如下:

1
2
3
4
5
6
7
8
9
10
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());
}
}

获取方法的指定的注解对象:

1
2
3
4
5
6
7
8
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());
}

参数的注解

给参数加注解也是可能的,比如:

1
2
3
4
5
public class TheClass {
public static void doSomethingElse(
@MyAnnotation(name="aName", value="aValue") String parameter){
}
}

获取方法参数的注解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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()方法返回了方法每个参数的注解值是一个一个二维的数组。

成员变量的注解

成员变量也是可以添加注解的比如:

1
2
3
4
5
public class TheClass {

@MyAnnotation(name="someName", value = "Hello World")
public String myField = null;
}

获取成员变量的所有的注解对象:

1
2
3
4
5
6
7
8
9
10
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());
}
}

获取指定的注解对象:

1
2
3
4
5
6
7
8
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());
}

原文

This article was last updated on days ago, and the information described in the article may have changed.