反射
1. 类加载器:
类的加载、类的连接、类的初始化
类的初始化:
- 假如该类还未被加载和连接,程序先加载并连接该类
- 假如该类的直接父类还未被初始化,先初始化其父类(初始化父类时也遵循这三个步骤)
- 假如类有初始化语句,系统依次执行这些初始化语句
类加载器:将.class文件加载到内存中 -- ClassLoader
- Bootstrap
- Platform class loader
- System class loader
2. 反射:
Java反射机制:指运行时获取一个类的变量和方法信息,通过获取的信息创建对象,调用方法的一种机制。增强程序灵活性,可以扩展
class类的对象
获取字节码文件对象:类.getClass、对象.getClass、forName
获取构造方法并创建对象
// 反射获取一个类的字节码文件
Class<?> c = Class.forName("com.itheima.Student");
// 获得多个(公共、所有)构造方法
Constructor<?>[] cons = c.getConstructors();
Constructor<?>[] dcons = c.getDeclaredConstructors();
// 获得单个构造方法
Constructor<Student> con = c.getConstructor(); // 无参构造
Constructor<Student> con = c.getConstructor(String.class, int.class, String.class); // 带参构造
// 根据构造方法创建单个对象
Student s = con.newInstance();
// 此处可能出现创建对象的构造方法是私有的,需要使用暴力反射方法创建
con.setAccessible(true)
获取成员变量并使用
Class<?> c = Class.forName("com.itheima.Student");
Constructor<?> con = c.getDeclaredConstructor();
Object o = con.newInstance();
// 获得成员变量
Field addressField = c.getDeclaredField("address");
addressField.setAccessible(true);
// 通过成员变量的set方法给对象中的成员赋值
addressField.set(o, "西安");
获取成员方法并使用
Class<?> c = Class.forName("com.itheima.Student");
Constructor<?> con = c.getDeclaredConstructor();
Object o = con.newInstance();
// 获取成员方法
// 这里两个方法之间区别不仅是公共和私有,getMethods会获取本类及超类所有公共方法,getDeclaredMethod只有本类所有方法
Method[] Methods = c.getMethods();
Method[] DeclaredMethods = c.getDeclaredMethods();
Method dMethod = c.getDeclaredMethod();
dMethod.setAccessible(true);
// 调用方法
dMethod.invoke(o, "用到的参数");
反射 - 运行配置文件指定内容
Properties prop = new Properties();
FileReader fr = new FileReader("com/itheima/class.txt");
prop.load(fr);
fr.close();
String className = prop.getProperty("className");
String methodName = prop.getProperty("methodName");
Class<?> c = Class.forName(className);
Constructor<?> dcon = c.getDeclaredConstructor();
dcon.setAccessible(true);
Object o = dcon.newInstance();
Method dMethod = c.getDeclaredMethod(methodName);
dMethod.setAccessible(true);
dMethod.invoke(o);