要想知道什么是反射,就需要先了解什么是正射,一般情况下,我们在使用某个类之前就已经确定它到底是什么类了,拿到手就直接可以使用new关键字来调用构造方法进行初始化,之后使用这个类的对象来进行操作。
package com.example.rookie.demo;
/**
* @author
* @date 2021/9/9 17:01
*/
public class Writer {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package com.example.rookie.demo;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @author
* @date 2021/9/9 17:01
*/
public class WriterDemo {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//正射
Writer writer = new Writer();
writer.setName("测试");
System.out.println(writer.getName());
//反射
//1、获取反射类的class对象
Class clazz = Class.forName("com.example.rookie.demo.Writer");
//2、通过class对象获取构造方法constructor对象
Constructor constructor = clazz.getConstructor();
//3、通过constructor对象初始化反射类对象
Object obj = constructor.newInstance();
//4、获取要调用方法的Method对象
Method setNameMethod = clazz.getMethod("setName", String.class);
//5、通过invoke方法执行
setNameMethod.invoke(obj, "反射测试");
Method getNameMethod = clazz.getMethod("getName");
Object result = getNameMethod.invoke(obj);
System.out.println(result);
}
}
可以看出,反射的成本要比正射高的多,由于反射涉及到动态解析,因此无法执行java虚拟机优化,在加上反射的写法的确要复杂的多,所以性能要比‘正射’差很多,在一些性能敏感的程序中应该避免使用反射。
反射的主要应用场景:
- 开发通用框架:如Spring,为了保持通用性,通过配置文件来加载不同的对象,调用不同的方法。
- 动态代理:在面向切面编程中,需要拦截特定的方法,就会选择动态代理的方式,而动态代理的底层技术就是反射。
- 注解:注解本身只是起到一个标记符的作用,它需要利用反射机制,根据标记符去执行特定的行为。