一、Java反射基础知识
1.什么是反射?
让程序在运行时可以动态的获取类的方法和属性等信息。反射使得Java程序能够动态地获取类的信息、创建对象、调用方法以及访问和修改类的属性。
2.反射的用途?
- 动态地创建对象: 通过 Class 对象的 newInstance() 方法创建对象。
- 动态地调用方法: 通过 Method 对象的 invoke() 方法调用方法。
- 动态地访问和修改属性: 通过 Field 对象的 get() 和 set() 方法访问和修改字段的值。
- 动态地操作数组: 通过 java.lang.reflect.Array 类的方法进行数组的创建和操作。
3.掌握反射底层需要掌握的知识
- 对象实例 -----对象就是通过new方法,在堆中创建一个实例。例如 String s = new String()。 s就是实例对象。
- 类 ----- 类是一种面向对象编程(Object-Oriented Programming,简称OOP)的基本构造。类是用于创建对象的蓝图或模板,定义了对象的属性(成员变量)和行为(方法)。对象是类的实例,通过类定义的结构和行为来创建。例如加载进入方法区中的String。
- Class -----在Java中,Class 对象是表示类的元数据的一种特殊对象。每个类在运行时都有一个关联的 Class 对象,该对象包含了有关类的信息,如类的名称、字段、方法、构造方法等。Class 对象允许在运行时对类进行反射性的操作,例如创建对象、调用方法、访问字段等。
二、 反射的使用方法
通过上面的介绍,我们知道Class对象中包含了类的名称、字段、方法、构造方法等。所以通过获取Class对象即可获得类的方法和属性。
因此,首先就是要获取Class对象
获取Class对象的四种方式
- Class.forName(类路径名)
Class.foaName(“com.mysql.cj.jdbc.Driver”) - 类.class
Driver.class - 对象.getClass。
(new Driver()).getClass. - ClassLoader
通过类加载器去加载
如何使用反射
链接: link
三、反射的底层原理
类加载的过程
类的加载主要分为 加载、链接、初始化
加载
1.主要是把类的字节流加载进入虚拟机。2.将字节流所代表的静态存储结构转换为方法区的运行时数据结构。
3.并且在堆中为Class对象分配空间,作为方法区中的数据访问入口。
链接
链接由包括验证、准备、解析
-
验证 —这一步主要是检查加载的字节流是否符合虚拟机中的规范,会不会对虚拟机的安全造成影响
-
准备 —主要是为静态变量在方法区中分配内存空间,并给静态变量赋初值。如果时final修饰的静态变量则直接赋值。从概念上讲,类变量所使用的内存都应当在 方法区 中进行分配。不过有一点需要注意的是:JDK 7 之前,HotSpot 使用永久代来实现方法区的时候,实现是完全符合这种逻辑概念的。 而在 JDK 7 及之后,HotSpot 已经把原本放在永久代的字符串常量池、静态变量等移动到堆中,这个时候类变量则会随着 Class 对象一起存放在 Java 堆中。
-
解析 --把常量池中的符号引用转换成直接引用的过程。 解析动作主要针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用限定符 7 类符号引用进行。
初始化
初始化阶段是执行初始化方法 ()方法的过程,是类加载的最后一步,这一步 JVM 才开始真正执行类中定义的 Java 程序代码(字节码)。
反射的原理讲解
对象在创建的过程中,都有一个字段指向Class对象。因此我们可以通过对象.getClass来获取Class对象。从而可以获取类的各种属性和方法。如下图