Java反射原理理解
导读
我们来看一下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反射原理理解相关推荐
- Java反射原理及应用
Java反射原理及应用 概述 底层原理 类加载 反射.直接调用的区别 反射调用性能 反射慢本质 反射应用场景 应用示例 概述 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性 ...
- 从Java代码到Java堆理解和优化您的应用程序的内存使用
从Java代码到Java堆理解和优化您的应用程序的内存使用 简介: 本文将为您提供 Java? 代码内存使用情况的深入见解,包括将 int 值置入一个Integer 对象的内存开销.对象委托的成本和不 ...
- JVM面试1 :谈谈你对Java的理解
谈谈你对Java的理解 如何查看字节码? 使用 javap
- java 反射获取属性名和值_面试官这样问我Java反射原理,我刚好都会
上周我投递出了简历,岗位是java后端开发工程师.这周美团面试官给我进行了面试,面试过程中他问了Java的反射原理.(不得不夸一句,美团的效率真高,上午面完一面,晚上二面马上安排上了.) 无论什么Ja ...
- Java——深入理解Java异常体系
Java--深入理解Java异常体系 参考文章: (1)Java--深入理解Java异常体系 (2)https://www.cnblogs.com/wugongzi/p/11858228.html 备 ...
- 面试官这样问我Java反射原理,我刚好都会
上周我投递出了简历,岗位是java后端开发工程师.这周美团面试官给我进行了面试,面试过程中他问了Java的反射原理.(不得不夸一句,美团的效率真高,上午面完一面,晚上二面马上安排上了.) 无论什么Ja ...
- 谈谈你对Java的理解
谈谈你对Java的理解 这个考察的很宽泛,答案不是唯一的,往往考察多个方面,其实这个问题考察的是你是否真的掌握了Java,对基础知识点的理解是否真的很清楚.是否掌握主要的模块和运行 原理等,同时也会对 ...
- 谈谈你对java的理解,java是“解释执行”这句话对吗?
谈谈你对java的理解,java是"解释执行"这句话对吗? 先科普下什么是"解释执行"? 什么是"编译执行"? • 解释执行 解释执行时高级 ...
- Java 深入理解深拷贝和浅拷贝区别
title: Java 深入理解深拷贝和浅拷贝区别 date: 2021-6-19 updated: 2021-6-19 tags: Java 深拷贝和浅拷贝 categories: 面试 Java ...
最新文章
- HDU1089-1096 A+B for Input-Output Practice 系列问题(输入输出格式练习)
- 山东省各2021高考成绩查询,关于2021年山东省高考成绩查询系统入口【官网】
- StringBuilder StringBuffer
- 与python相关的爬虫工具_python爬虫常用工具集合
- 中国超导产业投资风险及应用前景调研报告2021版
- python 测试multiprocessing多进程
- lxml 和 XPah (爬虫)
- ZooKeeper 之快速入门
- [ios][swift]UIButton
- 理解数据类型与数学运算:求和、温度转换2
- visual studio无法更新_VS Code Python 扩展 5 月更新
- 第k个数组中的最小值
- java用户登录记住密码_java项目中登陆时记住密码
- Deeping Learning for self-driving cars
- 学习ubuntu基础看完这一篇就够了,我是貔貅带你打开ubuntu的大门
- 如何使用小米手机对文档进行扫描
- 局部路径规划器teb_local_planner详解3:跟随全局planner
- 小额配资的短线交易操作主要有哪些技巧?
- 缓解疲劳,闻咖啡比喝咖啡更好
- 电脑上最好的3个小说阅读器