前言
我们在日常的开发中其实很少写反射,只知道有这么个东西,然而对于为什么用它却知之甚少。实际上,我们的框架中大量用到了这种概念。例如,当我们需要获取某个包下的类,并进行统一处理时,我们就需要知道这些类的名称,通过new 创建实例对象;但是如果我们不知道类有哪些,或者说我们只是在最底层封装的代码,对于用户定义的类名称根本不知道,这个时候,反射就起到作用了。下面让我们一起学习一下Java的动态获取的信息以及动态调用对象的方法的反射机制吧。
一、反射概述
反射: 反射是一种机制,利用该机制可以在程序运行过程中对类进行解剖并操作类中的所有成员(成员变量,成员方法,构造方法)。 如果从上面的反射的定义上来看,反射是什么不太容易理解。通俗的讲,我们日常开发中使用某个类时必定知道它是什么类,是用来做什么的。于是我们直接对这个类进行实例化,之后使用这个类对象进行操作。
Apple apple = new Apple(); //直接初始化 apple.setPrice(4); 复制代码
上面这样子进行类对象的初始化,我们可以理解为“正射”。而反射则是一开始并不知道我要初始化的类对象是什么,自然也无法使用 new 关键字来创建对象了。这时候,我们使用 JDK 提供的反射 API 进行反射调用:
Class clz = Class.forName("com.chenshuyi.reflect.Apple"); Method method = clz.getMethod("setPrice", int.class); Constructor constructor = clz.getConstructor(); Object object = constructor.newInstance(); method.invoke(object, 4); 复制代码
上面两段代码的执行结果,其实是完全一样的。但是其思路完全不一样,第一段代码在未运行时就已经确定了要运行的类(Apple),而第二段代码则是在运行时通过字符串值才得知要运行的类(com.chenshuyi.reflect.Apple)。
所以说什么是反射? 反射就是在运行时才知道要操作的类是什么,并且可以在运行时获取类的完整构造,并调用对应的方法。
1.1 反射过程
* 反射过程描述: 首先会有一个java文件,然后会编译成.class文件,字节码文件(会里面包含了当前这个类里面所有数据信息)会加载到内存, JVM负责管理,为了方便管理,它会将每一个加载进来的class文件生成一个对应的Class对象<对应的类型就是生成字节码之前java文件 对应的类名类型>,这个class对象它就代表对应的类(java文件),那么我们可以通过这个类对应的class对象获得这个类中的数据信息 (成员变量、成员方法、构造方法) 复制代码
结论:我们使用反射,其实就是获得某个类的Class对象,然后通过这个Class对象对这个类中的成员数据进行处理(调用执行)!
1.2 反射前提
我们必须得到这类的字节码文件(.class文件) ====>>> Class对象
Class:它是一个类,Class类的实例表示正在运行的Java应用程序中的类和接口。我们的一个类最终在内存中都是字节码,然后JVM会对每一个类对应的字节码生成一个Class对象!然后通过这个Class对象就可以访问类中的所有信息!
* Java类与Class对象的对应关系: 一个类 =======>>> 一个Class对象 类中的一个成员变量 ======>>>> 一个Field对象(在程序运行阶段为类中的成员变量赋值或者获取值) 类中的一个成员方法 ======>&