一、什么是反射Java 反射允许程序在运行时获取类的完整信息构造、属性、方法并且可以操作它们创建对象、赋值、调用方法无视 private 修饰符正常写代码必须要知道类名、方法名、而且不能访问privateStudent s new Student(); s.name 张三; s.study();反射写代码不知道具体细节依旧可以创建对象调用私有方法、修改私有属性//引号里面是类的位置 Class clazz Class.forName(com.test.Student);二、核心作用运行时获取类信息包名、类名、父类、接口、构造、属性、方法运行时创建对象哪怕构造器是 private运行时操作属性修改 / 获取 private、final、static 属性运行时调用方法调用 private 方法、静态方法框架底层核心技术Spring、MyBatis、SpringBoot 全靠反射三、反射的核心API首先要获取class对象后续的方法才可以实现类型核心类作用类对象Class?代表一个类反射的入口构造器Constructor操作构造方法创建对象属性Field操作成员变量赋值 / 取值方法Method调用普通 / 静态方法权限setAccessible(true)破解 private其中获取类对象有三种方式类名.class对象.getClass()Class.forName(全类名)这时候有个疑问反射是如何获取的呢先来了解一下类加载过程当我们在终端运行javac命令时会把源代码文件.java变成二进制字节码文件.class运行java命令后JVM启动开始处理.class文件生成类对象之后再创建实例对象在以上过程描述中分别对应获取class对象的三种方式1磁盘文件阶段如图左边中使用的是Class.forName(全类名)这是一种在运行时动态加载类的方式2在编译期间JVM处理.class文件使用的是类名.class这种方式不需要创建实例对象直接通过类名获取3运行时阶段创建了实例对象使用的是对象名.getClass()这个逻辑是当你有了一个实例对象时可以反向获取他所属类的Class对象虽然阶段不同但是无论哪种方式得到的都是同一个Class对象四、具体使用使用步骤1.获取Class对象对象入口2.获取要操作的成员构造/属性/方法3.开启暴力反射setAccessible(true)4.执行操作创建对象 / 赋值 / 调用方法在获取的时候方法分为两类有Drclared所有权限都可以获取无Declared只获取public权限1.获取成员变量 FieldgetDeclaredFields()获取当前类中所有变量private /default/protected /public不包含父类getFields()只获取public成员变量包含父类getDeclaredField(变量名)获取指定名字的单个变量任意权限getField(变量名)获取指定名字的public变量2.获取成员方法 MethodgetDeclaredMethods()获取本类所有方法private /default/protected /public不包含父类getMethods()只获取public方法包含父类getDeclaredMethod(show, String.class)获取指定方法任意权限getMethod(show, String.class)获取指定的public方法3.获取构造器 ConstructorgetDeclaredConstructors()获取本类所有构造器getConstructors()获取public构造器getDeclaredConstructor(String.class)获取指定参数的构造器getConstructor(参数类型...)获取指定public构造器4.暴力反射setAccessible(true)关闭Java 访问检查可以操作 private 构造、private 变量、private 方法那什么时候需要暴力反射什么时候不需要那就是看private使用private修饰的需要暴力反射非private不需要暴力反射5.创建对象实例分为有参和无参//无参 Animal animal1 (Animal) declaredConstructor.newInstance(); //有参 Animal animal2 (Animal) del2.newInstance(小猫);6.操作成员相关方法注意在获取之前private修饰的变量要进行暴力反射get获取成员变量值set修改成员变量值invoke实例对象调用成员方法五、反射优缺点优点运行时动态获取类信息、动态创建对象解耦提高程序灵活性框架底层核心技术缺点性能比正常代码慢破坏封装性可以访问私有成员代码复杂可读性差