第七章类加载和反射

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)

原文地址:https://www.cnblogs.com/JBLi/p/10474787.html