java反射  reflex  反射获取方法  反射获取属性

一、反射概念:

      1、一定是在运行状态中进行的

      2、对于任意一个实体类,都能够知道这个类的所有属性和方法

      3、对于任意一个对象,都能够调用它的任意方法和属性

     这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制

二、利用反射我们能做什么

     1、在运行时判断任意一个对象所属的类

     2、在运行时构造任意一个类的对象

     3、在运行时判断任意一个类所具有的成员变量和方法

     4、在运行时调用任意一个对象的方法

     5、生成动态代理

三、获取class对象

    三种方法

    1、Class.forname(全类名) (带异常处理 推荐使用)

//获取该对象的class
Class c3 = null;
try {
    c3 = Class.forName("com.test.Student");
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}
//打印获取的类名称
System.out.println("类名称:"+c3.getName());

2、类名.Class

/获取该对象的class
Class c2 = Person.class;
//打印获取的类名称
System.out.println("类名称:"+c2.getName());

3、对象.getclass()

//获取该对象的class
Class c1 = person.getClass();
//打印获取的类名称
System.out.println("类名称:"+c1.getName());

注意凡是反射必须是Class

 

四、反射获取方法

   1、第一步获取反射接口

//1、先获取反射的Class
Class<?> stuClass = null;
try {
    stuClass = Class.forName("com.test.Student");
    System.out.println(stuClass);
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}

   2、获取方法

       分2种

      ①获取所有的公共方法 本类以及父类中以及接口中所有的公共方法,符合访问修饰符规律 public的方法 private不行

      ②获取当前类的所有方法(1.忽略访问修饰符规律 2.只限当前类,不含父类)

//2、获取方法
    // 1)获取所有的公共方法   本类以及父类中以及接口中所有的方法,2.符合访问修饰符规律 public的方法 private不行
        Method[] methods = stuClass.getMethods();
        for (Method method : methods) {
            System.out.println("获取所有的方法:" + method);
        }
        // 2)获取当前类的所有方法(1.忽略访问修饰符规律 2.只限当前类)
        Method[] methods1 = stuClass.getDeclaredMethods();
        for (Method method : methods1) {
            System.out.println("获取当前类的方法:" + method);
        }

五、反射获取属性

     分2种

     1、首先,依旧要获取class

Class<?> stuClass = null;
try {
   stuClass = Class.forName("com.test.Student");
   System.out.println(stuClass);
} catch (ClassNotFoundException e) {
   e.printStackTrace();
}

     2、反射获取属性

        也分2种

       ①所有的公共属性 本类及其父类中的

       ②本类中的属性

//2、获取属性
        // 1)所有的公共属性  本类及其父类中的
        Field[] fields = stuClass.getFields();
        for (Field field : fields) {
            System.out.println("所有的公共public属性:" + field);
        }

        //  2)本类中的属性
        Field[] fields1 = stuClass.getDeclaredFields();
        for (Field field : fields1) {
            System.out.println("本类中的属性:" + field);
        }

六、反射操作属性     

    方法一:

    1、首先获取Class对象

    2、在获取Object对象

    3、在Object对象转为实例

    4、设置实例的属性

   上代码

//1、先获取反射的Class
        Class<?> stuClass = null;
        try {
            stuClass = Class.forName("com.test.Student");
            System.out.println(stuClass);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        //方法一
        // 1)获取对象
        Object instance = null;
        try {
            instance = stuClass.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        //2)、转化为实例
        Student stud = (Student)instance;
        //3)、设置实例的属性
        stud.setStuNum("10001");
        stud.setName("张三");

        System.out.println("1、重新设置的属性   姓名:"+stud.getName()+"  学号:"+stud.getStuNum());

  方法二:

    1、首先获取Class对象

    2、反射获取属性

    3、反射方法设置属性值

//1、先获取反射的Class
        Class<?> stuClass = null;
        try {
            stuClass = Class.forName("com.test.Student");
            System.out.println(stuClass);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }       
        Field stuNumField = null;
        Field stuClassNameField = null;
        Field stuGradeField = null;
        try {
            //2、反射获取属性
            stuNumField = stuClass.getDeclaredField("stuNum");    // private 属性
            stuClassNameField = stuClass.getDeclaredField("className");  // private 属性
            stuGradeField = stuClass.getDeclaredField("grade");   // public 属性
            //操作私有属性  一定要 设置 为true   public属性则不需  否则报错
            stuNumField.setAccessible(true);
            stuClassNameField.setAccessible(true);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        try {
            //3、给属性赋值
            stuNumField.set(stud,"10002");  //相当于stud.setStuNum("10002");
            stuClassNameField.set(stud,"计算机班");
            stuGradeField.set(stud,"一年级");
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        System.out.println("2、重新设置的属性   班级:"+stud.getClassName()+"  学号:"+stud.getStuNum()+"  年级:"+stud.getGrade());

注意:操作私有属性   setAccessible 方法一定要 设置 为true,   public属性则不需 否则报错

 

七、反射操作实例的方法

   步骤:

    1、先获取反射的Class

    2、获取需要操作的方法

setAccessible 设置为可利用 不然会报错,public方法则不需

    4、获取实例对象

    5、调用该方法

 

    给大佬奉茶:

//1、先获取反射的Class
        Class<?> stuClass = null;
        try {
            stuClass = Class.forName("com.test.Student");
            System.out.println(stuClass);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        Method method = null;
        try {
           //2、获取方法
            method = stuClass.getDeclaredMethod("setStuNum",String.class);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        //3、设置为可利用  不然会报错
        method.setAccessible(true);

        Student person = null;//将instance转化为Person
        try {
            //4、获取实例对象
            person = (Student)stuClass.newInstance();
            //5、调用该方法
            method.invoke(person,"10003");
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }catch (InvocationTargetException e) {
            e.printStackTrace();
        }

八、反射操作构造方法(构造方法分public和 private) 

     步骤:

    1、先获取反射的Class

    2、获取需要构造方法(分无参数和有参数 2种)

    3、调用构造方法(无参数和有参数 2种)

   上代码:

//1、先获取反射的Class
        Class<?> stuClass = null;
        try {
            stuClass = Class.forName("com.test.Student");
            System.out.println(stuClass);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        //获取全部公共构造方法 public
        Constructor<?>[] constructors = stuClass.getConstructors();
        for (Constructor constructor:constructors) {
            System.out.println("全部公共构造方法"+constructor);
        }
        //2、获取本类的公共构造方法
        Constructor<?>[] constructors02 = stuClass.getDeclaredConstructors();
        for (Constructor constructor:constructors02) {
            System.out.println("本类构造方法" + constructor);
        }

        try {
            //3-1获取指定  无参数的构造方法
            Constructor<?> constructor02 = stuClass.getConstructor();
            Student stud = null;
            try {
                //如果构造函数是private  一定要加入下面这句话  否则报错
                //constructor02.setAccessible(true);
                stud = (Student) constructor02.newInstance();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
            System.out.println("本类无参数构造方法的对象:"+stud);


            //3-2获取指定  有参数的构造方法
            Constructor<?> constructor03 = stuClass.getConstructor(String.class);
            Student stud2 = null;//转化为Person类
            try {

                //如果构造函数是private  一定要加入下面这句话  否则报错
                //constructor02.setAccessible(true);
                constructor03.setAccessible(true);
                //4 调用构造方法 传参
                stud2 = (Student)constructor03.newInstance("10004");
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
            System.out.println("本类指定的有参数的构造方法的对象:"+stud2);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

   九、使用反射给对象赋值通用方法

//动态给对象赋值
    public void setProperty(Object obj, String propertyName, Object value) throws 
    NoSuchFieldException, IllegalAccessException {
        Class<?> perclass = obj.getClass();
        Field field = perclass.getDeclaredField( propertyName);//获得属性
        field.setAccessible(true);//因为是私有的
        field.set(obj,value);//(对象,方法)
    }

  调用

//使用反射给对象赋值通用方法
        Student student = new Student();
        try {
            test.setProperty(student,"stuNum","10007");
            System.out.println("动态设置的属性为:stuNum="+student.getStuNum());
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }