好久之前,学过的反射
对反射有点一知半解,今天详细整理了一下
1. 获取Class的对象的方式
- Class.forName(“全类名”):将字节码文件加载进内存,返回class对象
多用于配置文件,将类名定义在配置文件中,读取文件,加载类 - 类名.class :通过类名的属性class获取
多用于参数的传递 - 对象.getclass(): getclass()方法任object类中定义看
多用于对象的获取字节码的方式 - 结论:同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获得的Class对象都是一样的
2. Class对象的功能
2.1 获取功能
- 获取成员变量
- Field[] getFields() : 获取所有的公有变量
- Field getField(string name):获取指定名称的公有变量
- Field[] getDeclaredFields():获取所有的成员变量
- Field getDeclaredField(string name):获取指定名称的变量
Class testClass = Test.class; // 获取类对象 Field field = testClass.getDeclaredField("name"); // 获取变量 field.setAccessible(true); // 解除私有 Test test = new Test(); Object string = field.get(test); // 获取私有的值 System.out.println("我是原来的:" + string); field.set(test, "lr"); // 修改私有的值 Object string1 = field.get(test); System.out.println("我是后来的:" + string1);
- 获取构造方法
- constructorgetconstructors()
- Constructorgetconstructor(类…parameterTypes)
- Constructor getDeclaredConstructor(类… parameterTypes)
- constructorgetDeclaredconstructors()
Class testClass = Test.class; // 获取类对象 Constructor constructor = testClass.getConstructor(String.class); // 获取构造方法 Object test = constructor.newInstance("张三"); // 实例化赋予初值 System.out.println(test);
- 获取成员方法
- Method[]getMethods()
- Method getHethod(string name,类… parameterTypes)
- Method[l getDeclaredMethods()
- Method getDeclaredMethod(string name,类… parameterTypes)
Class testClass = Test.class; // 获取类对象 Test test = new Test(); Method method = testClass.getMethod("test", int.class); // 放入实例化和参数 method.invoke(test, 1); // 运行该方法
- 获取类名
- String.getName()
- Field:成员变量
- 设置值
set() - 获取值
get() - 忽略访问权限修饰符
setAccessible(true)
- Constructor:构造方法
- 创建对象
- newInstance(Object… initargs)
- Method:方法对象
- 执行方法
- Object invoke(Object obj, Object… args)
- 获取方法名
- String getName:获取方法名
3. 案例
- 需求:写一个框架,不能改变该类的任何代码的前提下,可以帮我们创建任意类的对象,并且执行其中任意的方法
- 实现
- 配置文件
- 反射
- 步骤
- 将需要创建的对象的全类名和需要执行的方法定义在配置文件中
- 在程序中加载读取配置文件
- 使用反射技术来加载类文件进内存
- 创建方法
- 执行方法
Reflect.Class
package fanshe; import java.io.InputStream; import java.lang.reflect.Method; import java.util.Properties; public class Reflect { public static void main(String[] args) throws Exception { // 创建对象 Properties properties = new Properties(); // 获取类的加载器,可以找到src下的文件 ClassLoader classLoader = Reflect.class.getClassLoader(); // 读入文件 InputStream stream = classLoader.getResourceAsStream("pro.properties"); // 传入字节流 properties.load(stream); // 获取配置文件中数据 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.invoke(obj); } }
pro.properties
className=fanshe.Person methodName=sleep