一.概念:将类的各种组成部分封装为其他对象,这就是反射的机制
好处:可以在程序的运行过程中,操作这些对象
可以解偶提高程序的扩展性
二.获取字节码对象(Class对象)
Class.forName(类全路径): 可以把编译好的class文件加载到内存中,并且返回字节码对象
类名.class:获得内存中已有的字节码对象
类对象.getClass():通过对象获得内存中的字节码对象
三.字节码对象的操作
获取成员变量们
//获取所有public修饰的成员变量对象
Field [] getFields();
//获取指定名称的public的成员变量对象
Field getFields(String name);
//获取所有的成员变量对象,不考虑修饰符
Field [] getDeclareFields();
//获取指定名称的的成员变量对象不考虑修饰符
Field getDeclareFields(String name);
//成员变量对象的get和set方法,如果不是public修饰的需要执行忽略权限
field.setAccessible(true);//忽略权限修饰符(暴力反射)
field.get(对象);
field.set(对象,属性);
获取构造函数们
//获取所有public修饰的构造方法
Constructor<?>[] getConstructors();
//根据参数获得public修饰的构造方法
Constructor<T>[] getConstructor(类<?>...parameterTypes);
//获得所有的构造方法,不考虑修饰符
Constructor<?>[] getDeclareConstructors();
//根据参数获得构造方法,不考虑修饰符
Constructor<T>[] getDeclareConstructor(类<?>...parameterTypes);
//创建对象,如果不是public修饰的需要执行忽略权限,如果用无参构造的话直接可以Object.Class.newInstace();
constructor.setAccessible(true);//忽略权限修饰符(暴力反射)
Object obj=constructor.newInstace(构造参数1,构造参数2......)
获取成员函数们
//获取所有public修饰的成员方法,包括Object类的方法
Method [] getMethods();
//获取指定public修饰的成员方法,参数:方法名,属性字段....
Method [] getMethod(String name,类<?>...parameterTypes);
//获取所有成员方法,不考虑修饰符,包括Object类的方法
Method [] getDeclareMethods();
//获取指定的成员方法,不考虑修饰符,参数:方法名,属性字段对象...
Method [] getDeclareMethod(String name,类<?>...parameterTypes);
//执行方法,如果不是public修饰的需要执行忽略权
method.setAccessible(true);//忽略权限修饰符(暴力反射)
method.invoke(类对象,属性......)
//获取方法名
method.getName();
//获取全路径类名
String className=Object.class.getName();
四.案列
写一个"框架"来帮我们执行任意类的对象,并且执行其中的任意方法
public class ReflectTest {
public static void main(String[] args) throws Exception {
// 在不改变任意代码的情况下,可以创建任意类的对象,可以执行任意方法
//实现:
//1.配置文件
//2.反射
//步骤
//1.将需要创建的对象的全类名和需要执行的方法定义在配置文件中
//2.在程序中加载读取配置文件
//3.使用反射技术加载类文件进内存
//4.创建对象
//5.执行方法
Properties properties = new Properties();
InputStream ips = ReflectTest.class.getClassLoader().getResourceAsStream("pro.properties");
properties.load(ips);
String className = properties.getProperty("className");
String methodName = properties.getProperty("methodName");
Class<?> cls = Class.forName(className);
Object obj = cls.newInstance();
Method method = cls.getDeclaredMethod(methodName);
method.setAccessible(true);
method.invoke(obj);
}
}