通常写代码时,涉及调用关系,都是直接在另一个类中new一个对象,当需要更改或替换的时候就要重新修改代码,属于硬编码。让程序更加灵活,不用修改源代码重新编译,为了达到这个目的,需要在程序运行过程能够选择想要实例化的对象,因此出现了反射。
2、什么是反射
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
3、反射的功能
在运行时判断任意一个对象所属的类;
在运行时构造任意一个类的对象;
在运行时判断任意一个类所具有的成员变量和方法;
在运行时调用任意一个对象的方法;
4、实现反射
获得Class对象,就是获取到指定的名称的字节码文件对象。实例化对象,获得类的属性、方法或构造函数。访问属性、调用方法、调用构造函数创建对象。
5、注解的作用
注解最早的作用时生成文档,也就是我们写代码时添加的注释信息,可以通过注解直接生成javadoc文档;注解也可以替代配置文件,主要体现在一些框架的使用,如Spring,可以通过xml来配置,也可以使用注解的方式(主要);编译时格式检查。
6、利用反射实现注解
(1)、定义注解,使用元注解自定义注解
@Documented – 表示使用该注解的元素应被javadoc或类似工具文档化,它应用于类型声明,类型声明的注解会影响客户端对注解元素的使用。如果一个类型声明添加了Documented注解,那么它的注解会成为被注解元素的公共API的一部分。
@Target – 表示支持注解的程序元素的种类,一些可能的值有TYPE, METHOD, CONSTRUCTOR, FIELD等等。如果Target元注解不存在,那么该注解就可以使用在任何程序元素之上。
@Inherited – 表示一个注解类型会被自动继承,如果用户在类声明的时候查询注解类型,同时类声明中也没有这个类型的注解,那么注解类型会自动查询该类的父类,这个过程将会不停地重复,直到该类型的注解被找到为止,或是到达类结构的顶层(Object)。
@Retention – 表示注解类型保留时间的长短,它接收RetentionPolicy参数,可能的值有SOURCE, CLASS, 以及RUNTIME。
@Documented
@Inherited
@Target(ElementType.METHOD) //定义注解的使用地方,查看ElementType就可以知道
@Retention(RetentionPolicy.RUNTIME) //注解的生命周期
public @interface testlog {
String author() default "bird";
String date();
int revision() default 1;
String comments();
}
(2)为某个类添加注解
@testlog(author = "Tom", date = "2017", comments = "test")
public void getUser(String name) {
System.out.println("hello:"+name);
}
(3)解析注解
public void analyticMethod () throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
for (Method method : Test.class.getMethods()) {
// 查看该方法是否有注解
boolean flag = method.isAnnotationPresent(testlog.class);
Test test = new Test();
if (flag) {
// 该方法存在注解,需要遍历方法加在方法上的所有注解
testlog log = method.getAnnotation(testlog.class);
System.out.println(log.author()+"调用"+method.getName()+"方法");
method.invoke(test, "Tom");
}
}
}