第七章类加载和反射
spring核心就是 反射 和代理 代理称为动态代理
reflect反射
JAVA反射机制是在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。
Class获取方式
Class是Reflection故事起源。针对任何您想探勘的类,唯有先为它产生一个Class 对象,接下来才能经由后者唤起为数十多个的Reflection APIs
Class类的方法:反射可以越过泛型
getConstructors()
1、构造函数方法对象java.lang.reflect.Constructor
2、getConstructors()获取所有的public的构造函数
3、getDeclaredConstructors获取是该类声明的构造函数
getDeclaredConstructors() 获取类中的构造方法,并完成对象的创建 步骤: 1,获取Class对象 2,通过Class对象 ,获取到指定的构造方法 getConstructor(参数); 3,通过构造方法,创建对象 public T newInstance(Object... initargs) 私有构造方法,创建对象 1,获取class对象 2,通过class对象 ,获取到指定的构造方法 getDeclaredConstructor (参数); 3,暴力访问 c.setAccessible(true); 4,通过构造方法,创建对象 public T newInstance(Object... initargs)
@Test
public void test() {
try {
Class cp1 = Person.class;// 1.类名.Class
Person person = new Person();
Class cp2 = person.getClass();
Class cp3 = cp2.getSuperclass();
Class cp4 = Class.forName("com.bw.pojo.Person");
Class<Integer> cp5 = Integer.TYPE;
System.out.println(cp1);
System.out.println(cp2);
System.out.println(cp3);
System.out.println(cp4);
System.out.println(cp5);
} catch (Exception e) {
e.printStackTrace();
}
}
@Test//获取构造函数无参 public void test2() throws Exception { Class cp=Person.class; Class stu=Student.class; //获取所有的public构造函数getConstructors 构造函数是私有的获取不到 Constructor[] constructors = cp.getConstructors(); for (Constructor constructor : constructors) { System.out.println(constructor); } System.out.println("****************************************"); Constructor[] constructors1 = stu.getConstructors(); for (Constructor constructor1 : constructors1) { System.out.println(constructor1); } System.out.println("****************************************"); }
@Test//获取构造函数无参
public void test3() throws Exception {
Class cp=Person.class;
Class stu=Student.class;
//获取该类所有的构造函数 不管是private还是public 都可以获取
Constructor[] constructors = cp.getDeclaredConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
System.out.println("****************************************");
Constructor[] constructors1 = stu.getDeclaredConstructors();
for (Constructor constructor1 : constructors1) {
System.out.println(constructor1);
}
System.out.println("****************************************");
}
@Test//获取构造函数无参 public void test4() throws Exception {//public构造方法,创建对象
Class cp=Person.class; //1.获取指定的构造函数 Constructor con = cp.getDeclaredConstructor(String.class,int.class,String.class); //2.通过构造方法创建对象newInstance 前提是 构造方法是public修饰的 Person Per = (Person) con.newInstance("admin",5,"男"); System.out.println("创建的父类:"+Per); System.out.println("-----------------------------------------------"); //私有构造方法,创建对象 Class stu=Student.class; //2,通过class对象 ,获取到指定的构造方法getDeclaredConstructor (参数); Constructor con1 = stu.getDeclaredConstructor(String.class,double.class); //3,暴力访问 c.setAccessible(true); con1.setAccessible(true); //4,通过构造方法,创建对象//public T newInstance(Object... initargs) Student stu1 = (Student) con1.newInstance("学生",50); System.out.println("学生:"+stu1); }
运行结果:
getFields()
1、java.lang.reflect.Field
2、Field类封装了关于成员变量的操作
3、getFields()获取所有的public的成员变量 包含父类的成员变量
getDeclaredFields()
getDeclaredFields()获取是该类声明所有的成员变量含private的,不包含父类
公有成员变量的使用
1,获取Class对象
2,获取构造方法,创建对象
3,获取指定的成员变量
4,对成员变量赋值\获取值操作
public void set(Object obj(对象实例), Object value) 赋值
public Object get(Object obj) 获取值
私有成员变量的使用
1,获取class对象
2,获取构造方法,创建对象
3,获取指定的成员变量
4,开启暴力访问 把要修改变量setAccessible(true);
5,对成员变量赋值\获取值操作
public void set(Object obj, Object value) 赋值
public Object get(Object obj) 获取值
@Test
//获取成员变量
//getFields方法 获取的是 public修饰的成员变量
//包含父类的成员变量 private 修饰的成员变量 访问不到
public void testName() throws Exception {
Class cp=Person.class;
Class stu=Student.class;
Field[] fields = cp.getFields();
for (Field field : fields) {
System.out.println("人类的成员变量:"+field);
}
System.out.println("------------------------------");
Field[] fields1 = stu.getFields();
for (Field field1 : fields1) {
System.out.println("学生的成员变量:"+field1);
}
}
如图:
@Test
public void tes() throws Exception { Class cp=Person.class; Class stu=Student.class; Field[] fields = cp.getDeclaredFields(); for (Field field : fields) { System.out.println("人类的成员变量:"+field); } System.out.println("------------------------------"); Field[] fields1 = stu.getDeclaredFields(); for (Field field1 : fields1) { System.out.println("学生的成员变量:"+field1); } }
getMethods()
获取所有public的方法数组(包含父类或者父接口中继承下来的所有public方法)
// 获取方法的返回值类型的类类型
getReturnType();
// 获取方法的名称
getName();
// 获取参数的类型-->参数列表的类型的类类型
getParameterTypes();
等等
getDeclaredMethods()
包含该类或者接口中所有的方法,不包含从父类或者父接口中继承下来的
调用方法使用
invoke(obj, args);
obj表示实例类对象,args表示该方法需要传的参数
通过反射,调用方法
步骤:
1,获取Class对象
2,获取构造方法,创建对象
3,获取指定的public方法
4,执行方法
public Object invoke(Object obj, Object... args)
私有方法的调用:
1,获取Class对象
2,获取构造方法,创建对象
3,获取指定的private方法
4,开启暴力访问
c.setAccessible(true);
5,执行方法
public Object invoke(Object obj, Object... args)