导读

我们来看一下Oracle 官方文档中对反射的描述:

从Oracle 官方文档中可以看出,反射主要应用在以下几方面:

  • 反射让开发人员可以通过外部类的全路径名创建对象,并使用这些类,实现一些扩展的功能。
  • 反射让开发人员可以枚举出类的全部成员,包括构造函数、属性、方法。以帮助开发者写出正确的
  • 测试时可以利用反射API访问类的私有成员,以保证测试代码覆盖率。

也就是说,Oracle希望开发者将反射作为一个工具,用来帮助程序员实现本不可能实现的功能。现在我们来看看其执行流程。

反射获取类实例 Class.forName(“A.b.xxx”);

首先调用了 java.lang.Class 的静态方法,获取类信息.

 @CallerSensitivepublic static Class<?> forName(String className)throws ClassNotFoundException {// 先通过反射,获取调用进来的类信息,从而获取当前的 classLoaderClass<?> caller = Reflection.getCallerClass();// 调用native方法进行获取class信息return forName0(className, true, ClassLoader.getClassLoader(caller), caller);}

forName()反射获取类信息,并没有将实现留给了java,而是交给了jvm去加载。主要是先获取 ClassLoader, 然后调用 native 方法,获取信息,加载类则是回调 java.lang.ClassLoader。最后,jvm又会回调 ClassLoader 进类加载。

 // java.lang.ClassLoaderprotected Class<?> loadClass(String name, boolean resolve)throws ClassNotFoundException{// 先获取锁synchronized (getClassLoadingLock(name)) {// First, check if the class has already been loaded// 如果已经加载了的话,就不用再加载了Class<?> c = findLoadedClass(name);if (c == null) {long t0 = System.nanoTime();try {// 双亲委托加载if (parent != null) {c = parent.loadClass(name, false);} else {// 启动类加载器加载c = findBootstrapClassOrNull(name);}} catch (ClassNotFoundException e) {// ClassNotFoundException thrown if class not found// from the non-null parent class loader}// 父类没有加载到时,再自己加载if (c == null) {// If still not found, then invoke findClass in order// to find the class.long t1 = System.nanoTime();c = findClass(name);// this is the defining class loader; record the statssun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);sun.misc.PerfCounter.getFindClasses().increment();}}if (resolve) {resolveClass(c);}return c;}

newInstance()

newInstance() 主要做了三件事:

  • 权限检测,如果不通过直接抛出异常;
  • 查找无参构造器,并将其缓存起来;
  • 调用具体方法的无参构造方法,生成实例并返回;

class.getMethod()


上面的Class对象是在加载类时由JVM构造的,JVM为每个类管理一个独一无二的Class对象,这份Class对象里维护着该类的所有Method,Field,Constructor的cache,这份cache也可以被称作根对象

每次getMethod获取到的Method对象都持有对根对象的引用,因为一些重量级的Method的成员变量(主要是MethodAccessor),我们不希望每次创建Method对象都要重新初始化,于是所有代表同一个方法的Method对象都共享着根对象的MethodAccessor,每一次创建都会调用根对象的copy方法复制一份:

invoke()


调用Method.invoke之后,会直接去调MethodAccessor.invoke。MethodAccessor就是上面提到的所有同名method共享的一个实例,由ReflectionFactory创建。

总结

最后,用几句话总结反射的实现原理:

  • 反射类及反射方法的获取,都是通过从列表中搜寻查找匹配的方法,所以查找性能会随类的大小方法多少而变化;

  • 每个类都会有一个与之对应的Class实例,从而每个类都可以获取method反射方法,并作用到其他实例身上;

  • 反射也是考虑了线程安全的,放心使用;

  • 反射使用软引用relectionData缓存class信息,避免每次重新从jvm获取带来的开销;

  • 反射调用多次生成新代理Accessor, 而通过字节码生存的则考虑了卸载功能,所以会使用独立的类加载器;

  • 当找到需要的方法,都会copy一份出来,而不是使用原来的实例,从而保证数据隔离;

  • 调度反射方法,最终是由jvm执行invoke0()执行;

Java反射原理理解相关推荐

  1. Java反射原理及应用

    Java反射原理及应用 概述 底层原理 类加载 反射.直接调用的区别 反射调用性能 反射慢本质 反射应用场景 应用示例 概述 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性 ...

  2. 从Java代码到Java堆理解和优化您的应用程序的内存使用

    从Java代码到Java堆理解和优化您的应用程序的内存使用 简介: 本文将为您提供 Java? 代码内存使用情况的深入见解,包括将 int 值置入一个Integer 对象的内存开销.对象委托的成本和不 ...

  3. JVM面试1 :谈谈你对Java的理解

    谈谈你对Java的理解 如何查看字节码? 使用 javap

  4. java 反射获取属性名和值_面试官这样问我Java反射原理,我刚好都会

    上周我投递出了简历,岗位是java后端开发工程师.这周美团面试官给我进行了面试,面试过程中他问了Java的反射原理.(不得不夸一句,美团的效率真高,上午面完一面,晚上二面马上安排上了.) 无论什么Ja ...

  5. Java——深入理解Java异常体系

    Java--深入理解Java异常体系 参考文章: (1)Java--深入理解Java异常体系 (2)https://www.cnblogs.com/wugongzi/p/11858228.html 备 ...

  6. 面试官这样问我Java反射原理,我刚好都会

    上周我投递出了简历,岗位是java后端开发工程师.这周美团面试官给我进行了面试,面试过程中他问了Java的反射原理.(不得不夸一句,美团的效率真高,上午面完一面,晚上二面马上安排上了.) 无论什么Ja ...

  7. 谈谈你对Java的理解

    谈谈你对Java的理解 这个考察的很宽泛,答案不是唯一的,往往考察多个方面,其实这个问题考察的是你是否真的掌握了Java,对基础知识点的理解是否真的很清楚.是否掌握主要的模块和运行 原理等,同时也会对 ...

  8. 谈谈你对java的理解,java是“解释执行”这句话对吗?

    谈谈你对java的理解,java是"解释执行"这句话对吗? 先科普下什么是"解释执行"? 什么是"编译执行"? • 解释执行 解释执行时高级 ...

  9. Java 深入理解深拷贝和浅拷贝区别

    title: Java 深入理解深拷贝和浅拷贝区别 date: 2021-6-19 updated: 2021-6-19 tags: Java 深拷贝和浅拷贝 categories: 面试 Java ...

最新文章

  1. HDU1089-1096 A+B for Input-Output Practice 系列问题(输入输出格式练习)
  2. 山东省各2021高考成绩查询,关于2021年山东省高考成绩查询系统入口【官网】
  3. StringBuilder StringBuffer
  4. 与python相关的爬虫工具_python爬虫常用工具集合
  5. 中国超导产业投资风险及应用前景调研报告2021版
  6. python 测试multiprocessing多进程
  7. lxml 和 XPah (爬虫)
  8. ZooKeeper 之快速入门
  9. [ios][swift]UIButton
  10. 理解数据类型与数学运算:求和、温度转换2
  11. visual studio无法更新_VS Code Python 扩展 5 月更新
  12. 第k个数组中的最小值
  13. java用户登录记住密码_java项目中登陆时记住密码
  14. Deeping Learning for self-driving cars
  15. 学习ubuntu基础看完这一篇就够了,我是貔貅带你打开ubuntu的大门
  16. 如何使用小米手机对文档进行扫描
  17. 局部路径规划器teb_local_planner详解3:跟随全局planner
  18. 小额配资的短线交易操作主要有哪些技巧?
  19. 缓解疲劳,闻咖啡比喝咖啡更好
  20. 电脑上最好的3个小说阅读器

热门文章

  1. ASPROTECT 1.23RC4 脱壳分析
  2. 使用html+css实现一个静态页面【传统文化茶带音乐6页】HTML学生个人网站作业设计
  3. C#基础知识之依赖注入
  4. HIPAA解决方案(一、简介)
  5. 【数论】第1章 整数的可除性 第1节 整除概念与带余除法(3) 带余除法
  6. java cst比较大小_生成树CST、PVST、PVST+比较
  7. open3d读取可视化npy文件
  8. 微信公众号获取微信服务器IP地址
  9. 【数据结构:线性表】单链表
  10. 个人和企业的发展规划