注解其实是对类、方法、属性这些字节码的进一步修饰
通过注解,可以轻松地对这些字节码作进一步扩展,而不需要修改原有的内容
而反射可以获取到这些注解,那么就可以对运行时的实例对象做进一步处理
注解和反射形成配合,将字节码的一部分共性抽离出来,通用地处理
其实@Table,@Column这些JPA注解,也是通过注解和反射的配合来完成的
下面用一个简单的例子来描述注解和反射的配合:
先自定义一个注解MyAnnotation,注解里的text()用来存储一段文本信息
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
//在运行时注解依然存活
@Retention(value = RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
public String text();
}
算数类Calculation本身作用是求两个数之和 ,现在使用自定义的注解对它作修饰,目的是在求和之后打印多一句话。
public class Calculation {
@MyAnnotation(text = "The result is")
public int add(int a, int b){
return a + b;
}
}
最后写一个测试类
import java.lang.reflect.Method;
public class AnnotationTest {
public static void main(String[] args) throws Exception {
// 传入字节码
test(Calculation.class);
}
public static void test(Class<?> clazz) {
try {
// 根据参数,获取字节码里面的对应方法
Method method = clazz.getMethod("add", new Class[] { int.class, int.class });
// 通过字节码反射创建实例对象
Object object = clazz.newInstance();
// 获取方法上的MyAnnotation注解
if (method.isAnnotationPresent(MyAnnotation.class)) {
MyAnnotation ma = method.getAnnotation(MyAnnotation.class);
// 获取注解的内容
String text = ma.text();
// 反射调用实例对象的方法
Object result = method.invoke(object, new Object[] { 10, 1 });
System.out.println(text + " " + result);
}
} catch (Exception e) {
}
}
}
输出结果:The result is 11