首页 > 其他分享 >面试官:说说反射的底层实现原理?

面试官:说说反射的底层实现原理?

时间:2024-03-15 23:33:07浏览次数:20  
标签:反射 面试官 调用 Java invoke 实现 方法 底层

反射是 Java 面试中必问的面试题,但只有很少人能真正的理解“反射”并讲明白反射,更别说能说清楚它的底层实现原理了。所以本文就通过大白话的方式来系统的讲解一下反射,希望大家看完之后能真正的理解并掌握“反射”这项技术。

1.什么是反射?

反射在程序运行期间动态获取类和操纵类的一种技术。通过反射机制,可以在运行时动态地创建对象、调用方法、访问和修改属性,以及获取类的信息。

2.反射的应用有哪些?

反射在日常开发中使用的地方有很多,例如以下几个:

  1. 动态代理:反射是动态代理的底层实现,即在运行时动态地创建代理对象,并拦截和增强方法调用。这常用于实现 AOP 功能,如日志记录、事务管理等。
  2. Bean 创建:Spring/Spring Boot 项目中,在项目启动时,创建的 Bean 对象就是通过反射来实现的。
  3. JDBC 连接:JDBC 中的 DriverManager 类通过反射加载并注册数据库驱动,这是 Java 数据库连接的标准做法。

3.反射实现

反射的关键实现方法有以下几个:

  1. 得到类:Class.forName("类名")
  2. 得到所有字段:getDeclaredFields()
  3. 得到所有方法:getDeclaredMethods()
  4. 得到构造方法:getDeclaredConstructor()
  5. 得到实例:newInstance()
  6. 调用方法:invoke()

具体使用示例如下:

// 1.反射得到对象
Class<?> clazz = Class.forName("User");
// 2.得到方法
Method method = clazz.getDeclaredMethod("publicMethod");
// 3.得到静态方法
Method staticMethod = clazz.getDeclaredMethod("staticMethod");
// 4.执行静态方法
staticMethod.invoke(clazz);

反射执行私有方法代码实现如下:

// 1.反射得到对象
Class<?> clazz = Class.forName("User");
// 2.得到私有方法
Method privateMethod = clazz.getDeclaredMethod("privateMethod");
// 3.设置私有方法可访问
privateMethod.setAccessible(true);
// 4.得到实例
Object user = clazz.getDeclaredConstructor().newInstance();
// 5.执行私有方法
privateMethod.invoke(user);

4.底层实现原理

从上述内容可以看出,对于反射来说,操纵类最主要的方法是 invoke,所以搞懂了 invoke 方法的实现,也就搞定了反射的底层实现原理了。

invoke 方法的执行流程如下:

  1. 查找方法:当通过 java.lang.reflect.Method 对象调用 invoke 方法时,Java 虚拟机(JVM)首先确认该方法是否存在并可以访问。这包括检查方法的访问权限、方法签名是否匹配等。
  2. 安全检查:如果方法是私有的或受保护的,还需要进行访问权限的安全检查。如果当前调用者没有足够的权限访问这个方法,将抛出 IllegalAccessException。
  3. 参数转换和适配:invoke 方法接受一个对象实例和一组参数,需要将这些参数转换成对应方法签名所需要的类型,并且进行必要的类型检查和装箱拆箱操作。
  4. 方法调用:对于非私有方法,Java 反射实际上是通过 JNI(Java Native Interface,Java 本地接口)调用到 JVM 内部的 native 方法,例如 java.lang.reflect.Method.invoke0()。这个 native 方法负责完成真正的动态方法调用。对于 Java 方法,JVM 会通过方法表、虚方法表(vtable)进行查找和调用;对于非虚方法或者静态方法,JVM 会直接调用相应的方法实现。
  5. 异常处理:在执行方法的过程中,如果出现任何异常,JVM 会捕获并将异常包装成 InvocationTargetException 抛出,应用程序可以通过这个异常获取到原始异常信息。
  6. 返回结果:如果方法正常执行完毕,invoke 方法会返回方法的执行结果,或者如果方法返回类型是 void,则不返回任何值。

通过这种方式,Java 反射的 invoke 方法能够打破编译时的绑定,实现运行时动态调用对象的方法,提供了极大的灵活性,但也带来了运行时性能损耗和安全隐患(如破坏封装性、违反访问控制等)。

5.优缺点分析

反射的优点如下:

  1. 灵活性:使用反射可以在运行时动态加载类,而不需要在编译时就将类加载到程序中。这对于需要动态扩展程序功能的情况非常有用。
  2. 可扩展性:使用反射可以使程序更加灵活和可扩展,同时也可以提高程序的可维护性和可测试性。
  3. 实现更多功能:许多框架都使用反射来实现自动化配置和依赖注入等功能。例如,Spring 框架就使用反射来实现依赖注入。

反射的缺点如下:

  1. 性能问题:使用反射会带来一定的性能问题,因为反射需要在运行时动态获取类的信息,这比在编译时就获取信息要慢。
  2. 安全问题:使用反射可以访问和修改类的字段和方法,这可能会导致安全问题。因此,在使用反射时需要格外小心,确保不会对程序的安全性造成影响。

课后思考

为什么反射的执行效率比较低?动态代理的实现除了反射之外,还有没有其他的实现方法?

本文已收录到我的面试小站 www.javacn.site,其中包含的内容有:Redis、JVM、并发、并发、MySQL、Spring、Spring MVC、Spring Boot、Spring Cloud、MyBatis、设计模式、消息队列等模块。

标签:反射,面试官,调用,Java,invoke,实现,方法,底层
From: https://www.cnblogs.com/chinasoft/p/18076495

相关文章

  • SQL底层执行原理
    SQL底层执行原理#4.1SELECT语句的完整结构/*#sql92语法:SELECT....,....,....(存在聚合函数)FROM...,....,....WHERE多表的连接条件AND不包含聚合函数的过滤条件GROUPBY...,....HAVING包含聚合函数的过滤条件ORDERBY....,...(ASC/DESC)LIMIT...,....#sql99语法:SE......
  • 程序人生——Java泛型和反射的使用建议
    目录引出泛型和反射建议93:Java的泛型是类型擦除的建议94:不能初始化泛型参数和数组建议95:强制声明泛型的实际类型建议96:不同的场景使用不同的泛型通配符建议97:警惕泛型是不能协变和逆变的建议98:建议采用的顺序是List,List,List建议99:严格限定泛型类型采用多重界限建议1......
  • 提高反射的效率
    使用委托调用比直接调用慢10%,使用反射是直接调用的600倍,当然这取决于方法内部是否还外拉数据,但是反射转委托调用的好处显而易见所以我们需要使用反射和泛型方法来动态创建委托,并通过这些委托来调用特定的方法先创建一个带有返回值的publicclassRegisterDemo{privatest......
  • Docker使用(三)Docker底层分析
    Docker使用(三)Docker底层分析四、底层分析1、Docker镜像原理1.1commit镜像dockercommit提交容器成为一个新的副本#命令和git原理类似dockercommit-m=“提交的描述信息”-a=“作者”容器id目标镜像名:[TAG]实操:#1、启动一个默认tomcat#2、发现这个默认......
  • Redis zset 底层结构
    Rediszset底层结构  概要  在Redis的五种主要数据类型中,zset(有序集合)类型可能是最复杂,但也是最强大的一种。zset不仅可以存储键值对,还可以为每个元素分配一个分数,然后根据这个分数进行排序。这使得Zset非常适合用于实现排行榜、时间线等功能。  一、Zset底层结......
  • 一张图搞清楚wait、sleep、join、yield四者区别,面试官直接被征服!
    写在开头在线程的生命周期中,不同状态之间切换时,可以通过调用sleep()、wait()、join()、yield()等方法进行线程状态控制,针对这一部分知识点,面试官们也会做做文章,比如问你这些方法的作用以及之间的区别。那么今天我们就一起来总结一下这几个方法的作用及区别,先画一个思维导图梳理一......
  • go反射实战
    文章目录demo1数据类型判断demo2打印任意类型数据demo1数据类型判断使用reflect.TypeOf()方法打印go中数据类型,可参考go官方API文档;使用格式化参数%T也能打印数据类型。packagemainimport"fmt"import"reflect"import"io"import"os"funcmain(){ T......
  • 面试官:Spring Boot 微服务中你使用了哪些 starter maven 依赖项?这些 starter 到底是什
    该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点面试官:SpringBoot微服务中你使用了哪些startermaven依赖项在SpringBoot微服务中,可以使用大量的StarterMaven依赖项来简化项目配置和快速集成各种功能,包括......
  • 面试官:说说反射的底层实现原理?
    反射是Java面试中必问的面试题,但只有很少人能真正的理解“反射”并讲明白反射,更别说能说清楚它的底层实现原理了。所以本文就通过大白话的方式来系统的讲解一下反射,希望大家看完之后能真正的理解并掌握“反射”这项技术。1.什么是反射?反射在程序运行期间动态获取类和操纵类的......
  • 面试官:你还有什么想问我的?
    最近找我辅导面试的同学很多,我总结了一些案例,发现很多同学在面试环节,特别是面试官提问完毕的反问环节,经常犯一些比较低级的错误。当然,也不能完全称之为错误,毕竟网上很多所谓的面试教程都是这么教的。但在实际的面试过程中,如果你真的这么问,就可能会影响你的最终面试结果。挑选了......