类加载器与反射
当程序使用类的时候,类会被加载到内存中。整个过程分三步:
1.加载:将类文件加载到内存的堆中中,创建字节码文件对象。
2.连接,验证文件内部结构是否正确。
准备:为静态成员分配内存,并设置默认初始化值
解析:将类的二进制数据的符号引用换为直接引用
3.初始化
类加载器组成:
Bootstrap ClassLoader 根类加载器:负责java核心类的加载
Extension ClassLoader 扩展类加载器:负责jre的扩展目录的jar包的加载
System ClassLoader 系统类加载器:负责在JVM启动时加载来自java命令的class文件,以及classpath环境变量所指定的jar包和类路径。
反射是不通过对象直接调用类的一切属性和方法的方式。
步骤:(1)获取class对象
(2)通过class对象获取方法或属性
(3) 执行方法,修改属性
获取Class对象的三种方式 (1)Class c=Class.forName(路径);(2)对象.getClass (3)类名.class
获取方法的方式(1)获取构造方法 getConstructor()(2)获取普通方法getMethod()(3)获取一切方法(包括私有修饰的)getDeclaredMethod(4)获得一切构造方法与获得一般方法类同,也是加上Declared修饰
执行方法用invoke(),但若要执行私有方法,需要先将获得的私有方法setAccesible(true),才能执行。若修改私有成员变量也需要这样。
获取成员变量的方法 getField()(获取私有的成员变量与获取私有方法的方式类似),修改成员变量方法:set()。
下面是一个例子:
public class Demo01 { public static void main(String[] args) throws Exception { ti5(); } // ArrayList<Integer> list = new ArrayList<Integer>(); // 这个泛型为Integer的ArrayList中存放一个String类型的对象 public static void ti1() throws Exception, Exception{ ArrayList<Integer> list = new ArrayList<Integer>(); Class c=list.getClass(); Method method=c.getMethod("add",Object.class); method.invoke(list,"你好"); System.out.println(list); } //用反射去创建一个对象,有2种方式,尽量用代码去体现 public static void ti2() throws Exception{ Class c=Class.forName("com.java.demo.Person"); Object oj=c.newInstance(); System.out.println(oj); Constructor con=c.getConstructor(String.class,int.class,String.class); Object obj=con.newInstance("张三",18,"男"); System.out.println(obj); } //编写一个类,增加一个实例方法用于打印一条字符串。并使用反射手段创建该类的对象, 并调用该对象中的方法。 public static void ti3() throws Exception{ Class c=Class.forName("com.java.demo.Person"); Object obj=c.newInstance(); Method method=c.getMethod("run"); method.invoke(obj); } //定义一个标准的JavaBean,名叫Person,包含属性name、age。 // 使用反射的方式创建一个实例、调用构造函数初始化name、age,使用反射方式调用setName方法对名称进行设置, // 不使用setAge方法直接使用反射方式对age赋值。 public static void ti4() throws Exception{ Class c=Class.forName("com.java.demo.Person"); Constructor con=c.getConstructor(String.class,int.class,String.class); Object obj=con.newInstance("张三",14,"男"); System.out.println(obj); Method method=c.getMethod("setName", String.class); method.invoke(obj, "李四"); System.out.println(obj); Field field=c.getDeclaredField("age"); field.setAccessible(true); field.set(obj, 15); System.out.println(obj); } public static void ti5() throws IOException, Exception{ Properties pro=new Properties(); FileReader fr=new FileReader("pro.properties"); pro.load(fr); String demoName=pro.getProperty("DemoName"); Class c=Class.forName(demoName); Object obj=c.newInstance(); Method method=c.getMethod("run"); method.invoke(obj); } }