使用Java反射虚吟,您可以在運(yùn)行時(shí)訪問附加到Java類的注解御蒲。
什么是Java注釋掘剪?
注釋是Java 5中的一項(xiàng)新功能腻格。注釋是一種可以在Java代碼中插入的注釋或元數(shù)據(jù)画拾。 這些注釋可以在編譯時(shí)通過預(yù)編譯工具進(jìn)行處理,也可以在運(yùn)行時(shí)通過Java Reflection進(jìn)行處理菜职。 這是一個(gè)類注釋的例子:
@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();
}
前面的@標(biāo)記為注釋酬核。 一旦定義了注釋蜜另,就可以在代碼中使用它,如前面的示例所示嫡意。
注解定義中的兩條指令@Retention(RetentionPolicy.RUNTIME)和@Target(ElementType.TYPE)指定了注釋的使用方式举瑰。
@Retention(RetentionPolicy.RUNTIME)意味著注釋可以在運(yùn)行時(shí)通過反射來訪問。 如果你沒有設(shè)置這個(gè)指令蔬螟,注釋將不會(huì)在運(yùn)行時(shí)被保留下來此迅,因此不能通過反射來獲得。
@Target(ElementType.TYPE)意味著注釋只能在類型(通常是類和接口)的類上使用。 您也可以指定METHOD或FIELD邮屁,或者可以將目標(biāo)放在一起整袁,以便注釋可以用于類,方法和字段佑吝。
類注解
您可以在運(yùn)行時(shí)訪問類坐昙,方法或字段的注釋。 以下是訪問類注釋的示例:
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());
}
參數(shù)注釋
也可以為方法參數(shù)聲明添加注釋芋忿。
public class TheClass {
public static void doSomethingElse(
@MyAnnotation(name="aName", value="aValue") String parameter){
}
}
您可以像這樣訪問Method對(duì)象的參數(shù)注釋:
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());
}
}
}
請(qǐng)注意Method.getParameterAnnotations()方法如何返回一個(gè)二維Annotation數(shù)組炸客,其中包含每個(gè)方法參數(shù)的注釋數(shù)組。
字段注解
以下是帶注釋的字段示例:
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());
}
實(shí)戰(zhàn)
package com.reflection.detail;
import java.lang.annotation.Annotation;
/**
* Created by Fant.J.
* 2018/2/7 16:13
*/
public class Reflection_Annotations {
public static void main(String[] args) {
//獲取對(duì)象
Class aClass = People.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());
}
}
}
}
name: someName
value: Hello World
項(xiàng)目代碼:github鏈接