一、类的加载机制
类加载器负责将.class文件加载到内存中,并为之生成对应的Class对象
Class clazz = Class.forName(“类的全名”);
Class.forName("类的全名");
具体的反射加载:
使用Class类的forName()方法,加载(类的全名的)类的.class文件(字节码文件)到内存,
生成一个Class类的一个对象clazz,凡是使用类的全名创建的类对象都要使用这个clazz.
例子:
类的全名:com.cn.Student
//调用Class的forName()方法将,Student类的.class文件加载到内存
//同时生成一个clazz对象,这个clazz对象记录有Student类的结构信息(属性、构造方法、成员方法)
//凡是要生成Student类的对象例如stu1,stu2....都可以调用clazz对象来生成。
Class clazz = Class.forName("com.cn.Student");
反射的概念:
字节码文件的对象clazz的获取的三种方法(通过Class类、类名、对象来获取):
1.通过Class来获取 Class clazz = Class.forName("类名");
2.通过类名来获取 Class clazz = 类名.class; //.class为类名的类 中的一个静态属性,通过类名.静态方法类获取
3.通过对象来获取 Class clazz = 对象名.getClass();
以下程序证明这三种方式获取的clazz对象是同一个(同一个类clazz对象只生成一个)
二、反射获取构造方法创建对象
1、 clazz.newInstance()调用无参构造方法,生成该类的对象
例子:
使用clazz对象调用Student类的无参构造方法,生成Student类的对象stu1
Student stu1 = (Student)clazz.newInstance();
2、使用getConstructor
//获取带参构造方法 的一个实例constr
Consttructor constr= clazz.getConstructor(String.class,int.class);
//使用这个实例产生一个student对象stu1
Student stu1 = (Student) constr.newInstance("张三",23);
三、获取字段并修改stu1对象的name字段为李四
Class clazz = Class.forName("com.cn.Student");//获取字节码对象
Constructor constr=clazz.getConstructor(String.class,int.class);//获取Student类的构造方法
//调用构造方法创建stu1对象
Student stu1=(Student)constr.newInstance("张三",23);
//获取Student类字段(属性)//姓名字段(暴力反射方法)
Field nameField=clazz.getDeclaredField("name");
//去除私有权限
nameField.setAccessible(true);
fieldName.set(stu1,"李四");
System.out.println(stu1);
3.调用方法
四、调用有参方法
五、泛型擦除(反射)
在运行期跳过泛型监测在list中添加String类型的数据
获取构造用参数 (类型.class)
clazz.getConstructor(String.class,int.class);
获取字段用字段名()
clazz.getDeclaredField("字段名");
获取方法用方法名()
Methord m = clazz.getMethord("eat");
m.invoke(p,参数)