Java反射机制:
    是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;
    对于任意一个对象,都能够调用它的任意方法和属性;
    这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制;

    利用反射可以无视修饰符获取类里面所有的属性和方法。
    先获取配置文件中的信息,动态获取信息并创建对象和调用方法。
    利用反射调用它类中的属性和方法时,无视修饰符。

    获取Class类的对象:
    反射类.png
    获取class对象三种方式:

    获取CLASS对象的方式 作用
    类名.class 通过类名的属性class获取
    Class.forName(“类全名”) 通过指定的字符串路径获取
    对象.getClass() 通过对象的getClass()方法获取
    1. // 1.Class类中的静态方法forName("全类名")
    2. Class clazz = Class.forName("reflect.Student");
    3. System.out.println(clazz);
    4. // 2.通过class属性来获取
    5. Class clazz2 = Student.class;
    6. System.out.println(clazz2);
    7. // 3.利用对象getClass方法来获取
    8. // getClass方法是定义在Object类中
    9. Student student = new Student();
    10. Class clazz3 = student.getClass();
    11. System.out.println(clazz3);

    一个类中可以把成员变量认为成员变量对象:Field
    构造方式认为构造方法对象:Constructor
    成员方法认为成员方法对象:Method
    类对象2.png

    反射获取构造方法对象:

    对象.getConstructors() 获取所有public对象 返回一个数组[]
    对象.getDeclaredConstructors() 获取所有public、private对象 返回一个数组[]
    对象.getConstructor() 返回单个public构造方法对象,()里需要和构造方法保持一致 返回构造方法对象
    对象.getDeclaredConstructor() 获取私有的private构造方法,()里需要和构造方法保持一致 返回构造方法对象
    1. // 1、获取class对象
    2. Class clazz = Class.forName("reflect.Student2");
    3. // 2、获取所有公共的构造方法
    4. Constructor[] constructors = clazz.getConstructors();
    5. for (Constructor constructor : constructors) {
    6. System.out.println(constructor);
    7. }
    8. // 3、获取所有构造方法,private+public
    9. Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
    10. for (Constructor declaredConstructor : declaredConstructors) {
    11. System.out.println(declaredConstructor);
    12. }
    13. // 4、获取单个public构造方法,有参构造获取需要和构造方法保持一致
    14. Constructor constructor = clazz.getConstructor();
    15. System.out.println(constructor);
    16. Constructor constructor1 = clazz.getConstructor(String.class, int.class);
    17. System.out.println(constructor1);
    18. // 5、获取单个私有构造方法,有参构造获取需要和构造方法保持一致
    19. Constructor declaredConstructor = clazz.getDeclaredConstructor(String.class);
    20. System.out.println(declaredConstructor);

    反射获取构造方法并使用:

    构造方法对象.newInstance(参数) 用于创建一个对象

    ps:如果需要使用私有方法创建对象必须用私有构造方法对象.setAccessible(true);临时取消访问检查

    1. // 1、获取class对象
    2. Class clazz = Class.forName("reflect.Student");
    3. // 2、获取构造方法对象,有参构造
    4. Constructor constructor = clazz.getConstructor(String.class, int.class);
    5. //3、利用newInstance创建Student对象
    6. Student student = (Student) constructor.newInstance("zhangsan", 23);
    7. System.out.println(student);
    8. // 无参构造创建
    9. // 1、获取class对象
    10. Class clazz = Class.forName("reflect.Student2");
    11. Student student = (Student) clazz.newInstance();
    12. System.out.println(student);
    13. // 私有构造方法创建对象
    14. // 1、获取class对象
    15. Class clazz = Class.forName("reflect.Student2");
    16. // 2、获取一个私有构造方法
    17. Constructor declaredConstructor = clazz.getDeclaredConstructor(String.class);
    18. // 3、被私有的构造方法不能直接创建对象,如果需要使用,必须用私有构造方法.setAccessible(true);临时取消访问检查
    19. declaredConstructor.setAccessible(true);
    20. // 4、创建对象
    21. Student2 student = (Student2) declaredConstructor.newInstance("张三");
    22. System.out.println(student);

    获取成员变量(Field)对象:

    类对象.getFields(); 获取所有public成员变量对象
    类对象.getDeclaredFields(); 获取所有成员变量对象(包括私有变量)
    类对象.getField(“变量名”); 返回单个公共的成员变量
    类对象.getDeclaredField(“变量名”); 获取单个私有成员变量
    1. // 1、获取class对象
    2. Class clazz = Class.forName("reflect.StudentDemo");
    3. // 2、获取所有public成员变量对象
    4. Field[] fields = clazz.getFields();
    5. for (Field field : fields) {
    6. System.out.println(field);
    7. }
    8. // 3、获取所有成员变量对象
    9. Field[] Fields = clazz.getDeclaredFields();
    10. for (Field field : Fields) {
    11. System.out.println(field);
    12. }
    13. // 4、返回单个公共的成员变量
    14. Field field = clazz.getField("name");
    15. System.out.println(field);
    16. // 5、获取单个私有成员变量
    17. Field field2 = clazz.getDeclaredField("money");
    18. System.out.println(field);

    反射获取成员变量并使用

    变量对象.set(对象,变量) 使用变量对象.set,参数一传入一个实例对象,参数二传入需要保存的值
    变量对象.get(对象) 获取对象变量值
    1. // 1、创建class对象
    2. Class clazz = Class.forName("com.edu.info.ReflectDemo.Student");
    3. // 2、获取成员变量
    4. Field field = clazz.getField("name");
    5. // 3、创建对象
    6. Student student = (Student) clazz.newInstance();
    7. // 4、set赋值
    8. field.set(student,"zhangsan");
    9. System.out.println(student);
    10. -----------------------------------
    11. // 1、创建class对象
    12. Class clazz = Class.forName("com.edu.info.ReflectDemo.Student");
    13. // 创建变量对象
    14. Field field = clazz.getDeclaredField("money");
    15. // 设置允许临时访问
    16. field.setAccessible(true);
    17. // 创建类实例对象
    18. Student student = (Student) clazz.newInstance();
    19. // 根据变量对象查询值
    20. Object o = field.get(student);
    21. System.out.println(o);

    获取成员方法:

    clazz.getMethods(); 获取所有公共成员方法,包括继承的父类
    clazz.getDeclaredMethods(); 获取所有成员方法,不包括父类
    clazz.getMethod(“function1”); 获取一个指定的公共成员方法
    clazz.getMethod(“function2”, String.class); 获取一个指定的公共方法,带参数的
    clazz.getDeclaredMethod(“show”); 获取一个私有方法
    1. Class clazz = Class.forName("com.edu.info.ReflectDemo.Student2");
    2. // 1.获取所有公共成员方法,包括继承的父类
    3. Method[] methods = clazz.getMethods();
    4. for (Method method : methods) {
    5. System.out.println(method);
    6. }
    7. // 2.获取所有成员方法,不包括继承的
    8. Method[] methods = clazz.getDeclaredMethods();
    9. for (Method method : methods) {
    10. System.out.println(method);
    11. }
    12. // 3.获取一个指定的公共成员方法
    13. Method method = clazz.getMethod("function1");
    14. System.out.println(method);
    15. // 4.获取一个指定的公共方法,带参数的
    16. Method method = clazz.getMethod("function2", String.class);
    17. System.out.println(method);
    18. // 5.获取一个私有方法
    19. Method method = clazz.getDeclaredMethod("show");
    20. System.out.println(method);

    反射回去成员方法并运行
    Object invoke(Object obj,Objcet…args):运行方法
    参数一:用obj对象调用该方法
    参数二:调用方法穿的的参数(没有则不写)
    返回值 :方法的返回值(没有则不写)

    1. // 1、创建class对象
    2. Class clazz = Class.forName("com.edu.info.ReflectDemo.Student2");
    3. // 2、获取method对象
    4. Method method = clazz.getMethod("function4", String.class);
    5. // invoke参数一需要调用者对象,所有创建student对象
    6. Student2 student = (Student2) clazz.newInstance();
    7. // 参数一调用对象,参数二形参,用result接受返回值,没有返回值则不用接收
    8. Object result = method.invoke(student, "zhangsan");
    9. System.out.println(result);