美文网首页
JVM反射机制

JVM反射机制

作者: 自天佑之吉无不利 | 来源:发表于2023-09-12 12:19 被阅读0次

反射是什么?

反射(Reflection)是 JVM 提供的运行时机制 ,它允许程序在运行期借助  Reflection API 动态加载类或获取任何类的内部信息,动态创建对象并调用其属性,即使对象类型在编译期还是未知的。而我们通常写的程序,对象的类型是在编译期就确定下来的。就像上面说到的饭店的菜单,每道菜品是固定的,无法变更。

而反射赋予了我们动态创建菜品和调整菜品的能力。所以说,虽然 Java 是一种静态语言,但是反射机制的存在使 Java 也具有了动态性,具备了运行时自我认知的能力。这样我们就可以在运行时观察甚至修改 JVM 的行为。就像进入饭店的后厨,可以观察甚至调整我们的菜品。

反射的实现原理

反射机制的实现依赖于我们前两节课讲过的类加载机制,我们知道类加载的结果,除了把类的.class  文件中的二进制数据读入内存,并放到运行时数据区的方法区,JVM 还为我们在堆上创建了一个 java.lang.Class  对象,用来封装类在方法区内的数据结构,并且向我们提供了访问方法区内的数据结构的接口。

这个 Class 对象就是反射机制的核心,它就像打开 JVM 这个厨房的钥匙,赋予了我们打造专属于自己的菜品的能力。是不是感觉很酷,那我们应该怎么更好地利用这种能力呢?

反射执行步骤

有了上述 API ,我们可以按下面的步骤完成反射机制的调用。

我们需要先获取想要操作的类的 Class 对象。

通过调用 Class 类中的方法,获得我们需要的 Method、Field 类对象。

借助反射 API,操作这些对象,完成定制。

获取 Class 对象

获得这把钥匙的方式有 3 种。

• Class.forName

使用 Class 类的静态方法 forName(String className),这种方法需要传入类的全限定名,可以动态加载类,并触发静态代码块的执行,一般用于加载驱动和框架的底层操作。但是因为这个方法可能会抛出 ClassNotFoundException 异常,所以你需要处理这种可能性。

• .class 语法

对于任何类型的.class 都可以获取对应的 Class 对象。这是最直接、最简单的方式,不需要处理异常,但弊端也很明显,就是必须在编译期就知道具体的类,类似于厨房里本可以提供 100 道菜,但是菜单上只是写了 10 道菜,而你只能操作这菜单上面的 10 道菜,动态性大打折扣。

• Object 类的方法  getClass()

这种方法不需要类的完全限定名,只需要获取对象实例的类型。但是,你需要一个对象实例,所以在没有实例的情况下这种方法就没办法使用了。

第二层境界:运行时动态扩展 JVM 的提供能力

动态创建对象

当需要基于运行时的条件创建不同类型的对象时,反射机制是必需的。

创建对象有两种方法。

使用 Class 对象的 newInstance() 方法来创建该 Class 对象对应类的实例,但是这种方法要求该 Class 对象对应的类有默认的空构造器。

先使用 Class 对象获取指定的 Constructor 对象,再调用 Constructor 对象的 newInstance() 方法来创建 Class 对象对应类的实例,通过这种方法可以选定构造方法创建实例。

第三层境界:基于 JVM 提供的能力打造一个定制的图灵机

其实我们非常熟悉的 Spring 框架 ,正是借助反射机制,实现了我们说的使用 JVM 的第三层境界。Spring 封装了 JVM 底层的能力,通过 Bean 对外提供服务,而不是使用 Java 的 Object,这里的 Bean 就像我们封装了饭店后厨的能力打造的新菜单。

而这一切都离不开反射机制的支持,不管是依赖注入还是 AOP 编程,都使用到了反射机制。比如在依赖注入时,Spring 会通过反射调用 Bean 的 setter 方法或者构造器来实现依赖关系的注入;在 AOP 编程中,Spring 则是通过反射调用目标方法,并在调用之前或之后添加增强处理,从而实现面向切面编程。

为了方便你看清其中的本质,我把反射在 Spring 中的应用过程抽象成了 3 个步骤。

第一步:Spring 通过反射的方式创建 Bean 实例。在 Spring 中,对于配置的 Bean,其创建工作是由 BeanFactory 完成的。在 AbstractBeanFactory 类的 doCreateBean 方法中,调用 createBeanInstance 方法创建 Bean 实例,这个过程使用了反射技术。

第二步:Spring 通过反射设置属性值。在 BeanPostProcessor 后置处理器中,Spring 会读取属性配置,使用反射调用 set 方法为 Bean 的属性设置值。

第三步:Spring 通过反射调用 Bean 的生命周期回调方法,如 init-method 和 destroy-method。

此文章为9月Day11学习笔记,内容来源于极客时间《云时代JVM实战 》,强烈推荐该课程

相关文章

  • Java学习day-23:反射机制

    一、反射机制_Class对象获取: 1.反射机制: 反射机制是java的动态性之一;一个类被加载后,JVM 会创建...

  • Java反射

    简单总结下什么是Java反射,怎么使用。 Java反射机制 反射就是指JVM运行期,获取指定类所有的属性和方法的一...

  • Java类加载机制

    类加载机制 在Java面试中类加载机制是十分常见的考察点,时常和JVM内存模型,JVM内存管理,反射等知识点穿插考...

  • JVM--类加载与反射

    对JVM的内存有了一定理解后,再来看JVM是如何加载类,以及Java的反射机制 一、类加载过程 有了前面的了解,我...

  • java反射机制

    java的反射机制 1 JAVA的反射机制是什么?反射机制能做什么?反射机制的优点与缺点2 认识 Class...

  • java反射机制JVM加载类

    一:反射 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能...

  • 反射之一

    总结内容源自一下文章粗浅看java反射机制反射机制应用实践谈谈java反射机制Java Reflection(反射...

  • 反射之二

    总结内容源自一下文章粗浅看java反射机制反射机制应用实践谈谈java反射机制Java Reflection(反射...

  • Java反射机制入门

    Java反射机制入门 一、什么是反射 JAVA反射机制(The JAVA reflection mechanism...

  • JVM——类加载机制

    前言 今天就来介绍类的加载机制以及双亲委派机制。 JVM 类加载机制 JVM 类加载的五个阶段 JVM 类加载机制...

网友评论

      本文标题:JVM反射机制

      本文链接:https://www.haomeiwen.com/subject/wzdevdtx.html