好久之前,学过的反射
对反射有点一知半解,今天详细整理了一下
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);
-
获取构造方法
- constructor<?>getconstructors()
- Constructorgetconstructor(类<?>…parameterTypes)
- Constructor getDeclaredConstructor(类<?>… parameterTypes)
- constructor<?>getDeclaredconstructors()
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