1.反射的概述

什么是反射?

反射允许对成员变量,成员方法和构造方法的信息进行编程访问

先学习如何获取字节码文件的对象,再学习如何从字节码文件里面获取到字段、构造方法、成员方法,然后再解刨获取到里面的每一个信息

2.获取class对象的三种方式

①Class.forName("全类名");

②类名.class

③对象.getClass();

3.反射获取构造方法

Class类中用于获取构造方法的方法
方法 说明
Constructor<?>[ ] getConstructors() 返回所有公共构造方法对象的数组
Constructor<?>[ ]getDeclaredConstructors() 返回所有构造方法对象的数组
Constructor<T> getConstructor(Class<?>..parameterTypes) 返回单个公共构造方法对象
Constructor<T> getDeclaredConstructor(Class<?>..parameterTypes) 返回单个构造方法对象
Constructor类中用于创建对象的方法
方法 说明
T newInstance(Object...initargs) 根据指定的构造方法创建对象
setAccessible(boolean flag) 设置为true,表示取消访问检查


package com.dan.myreflect2;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Parameter;

public class MyReflectDemo2 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        /**
         *Constructor<?>[ ] getConstructors()	返回所有公共构造方法对象的数组
         * Constructor<?>[ ]getDeclaredConstructors()	返回所有构造方法对象的数组
         * Constructor<T> getConstructor(Class<?>..parameterTypes)	返回单个公共构造方法对象
         * Constructor<T> getDeclaredConstructor(Class<?>..parameterTypes)	返回单个构造方法对象
         *
         * T newInstance(Object...initargs)	根据指定的构造方法创建对象
         * setAccessible(boolean flag)	设置为true,表示取消访问检查
         */

        //1.获取class字节码文件对象
        Class clazz = Class.forName("com.dan.myreflect2.Student");

        //2.获取构造方法
        Constructor[] cons = clazz.getConstructors();
        for (Constructor con : cons) {
            System.out.println(con);
        }
        System.out.println("-----------");

        Constructor[] cons2 = clazz.getDeclaredConstructors();
        for (Constructor con : cons2) {
            System.out.println(con);
        }
        System.out.println("-----------");

        Constructor con3 = clazz.getConstructor();
        System.out.println(con3);
        System.out.println("-----------");

        Constructor con4 = clazz.getDeclaredConstructor(int.class);
        System.out.println(con4);
        System.out.println("-----------");

        Constructor con5 = clazz.getDeclaredConstructor(String.class,int.class);
        System.out.println(con5);
        System.out.println("-----------");

        int modifiers = con5.getModifiers();
        System.out.println(modifiers);
        System.out.println("-----------");

        Parameter[] parameters = con5.getParameters();
        for (Parameter parameter : parameters) {
            System.out.println(parameter);
        }
        System.out.println("-----------");

        //暴力反射:表示临时取消权限校验
        con5.setAccessible(true);
        Student stu = (Student) con5.newInstance("张三", 21);
        System.out.println(stu);

    }
}

4.反射获取成员变量

Class类中用于获取成员变量的方法
方法 说明
Field[ ] getFields() 返回所有公共成员变量对象的数组
Field[ ]getDeclaredFields() 返回所有成员变量对象的数组
Field getField(String name) 返回单个公共成员变量对象
Field getDeclaredField(String name) 返回单个成员变量对象
Field类中用于创建对象的方法
方法 说明
void set(Object obj, Object value) 赋值
Object get(Object obj) 获取值
package com.dan.myreflect3;

import java.lang.reflect.Field;

public class MyReflectDemo3 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
        /**
         *Field[ ] getFields()	返回所有公共成员变量对象的数组
         * Field[ ]getDeclaredFields()	返回所有成员变量对象的数组
         * Field getField(String name)	返回单个公共成员变量对象
         * Field getDeclaredField(String name)	返回单个成员变量对象
         *
         * void set(Object obj, Object value)	赋值
         * Object get(Object obj)	获取值
         */

        //1.获取class字节码文件的对象
        Class clazz  = Class.forName("com.dan.myreflect3.Student");

        //2.获取所有的成员变量
        Field[] fields = clazz.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }
        System.out.println("--------");

        //3.获取单个的成员变量
        Field name = clazz.getDeclaredField("name");
        System.out.println(name);
        System.out.println("--------");

        //获取权限修饰符
        int modifiers = name.getModifiers();
        System.out.println(modifiers);
        System.out.println("--------");

        //获取成员变量的名字
        String n = name.getName();
        System.out.println(n);
        System.out.println("--------");

        //获取成员变量的类型
        Class<?> type = name.getType();
        System.out.println(type);
        System.out.println("--------");

        //获取成员变量记录的值
        Student s = new Student("zhangsan",23,"男");
        name.setAccessible(true);
        Object value = name.get(s);
        System.out.println(value);
        System.out.println("---------");

        //修改对象里面记录的值
        name.set(s,"lisi");
        System.out.println(s);
    }
}

5.反射获取成员方法

Class类中用于获取成员方法的方法
方法 说明
Method[ ]getMethods() 返回所有公共成员方法对象的数组,包括继承的
Method[ ]getDeclaredMethods() 返回所有成员方法对象的数组,不包括继承的
Method getMethod(String name,Class<?>...parameterTypes) 返回单个公共成员方法对象
Method getDeclaredMethod(String name, Clas<?>..parameterTypes) 返回单个成员方法对象


Method类中用于创建对象的方法
Object invoke(Object obj, Object.. args):运行方法
参数一:用obj对象调用该方法
参数二:调用方法的传递的参数(如果没有就不写)
返回值:方法的返回值(如果没有就不写)

package com.dan.myreflect4;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

public class MyReflectDemo4 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        
        //1.获取class字节码文件对象
        Class<?> clazz = Class.forName("com.dan.myreflect4.Student");

        //2.获取里面所有的方法对象(包含父类中的所有的公共方法)
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
        System.out.println("----------");

        //获取里面的所有方法对象(不能获取父类的方法对象)
        Method[] methods2 = clazz.getDeclaredMethods();
        for (Method method : methods2) {
            System.out.println(method);
        }
        System.out.println("----------");

        //获取指定的单一方法
        Method m = clazz.getDeclaredMethod("eat",String.class);
        System.out.println(m);
        System.out.println("----------");

        //获取方法的修饰符
        int modifiers = m.getModifiers();
        System.out.println(modifiers);
        System.out.println("----------");

        //获取方法的名字
        String name = m.getName();
        System.out.println(name);
        System.out.println("----------");

        //获取方法的形参
        Parameter[] parameters = m.getParameters();
        for (Parameter parameter : parameters) {
            System.out.println(parameter);
        }
        System.out.println("----------");

        //获取方法的抛出异常
        Class<?>[] exceptionTypes = m.getExceptionTypes();
        for (Class<?> exceptionType : exceptionTypes) {
            System.out.println(exceptionType);
        }
        System.out.println("----------");


        //方法运行
        Student s = new Student();
        m.setAccessible(true);
        //参数一:s表示方法的调用者
        //参数二:“汉堡”表示在调用方法的时候传递的实际参数
        m.invoke(s,"汉堡");

    }
}

6.反射的作用

①获取一个类里面所有的信息,获取到了之后,再执行其他的业务逻辑

②结合配置文件,动态的创建对象并调用方法

 

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐