【五一创作】Java 反射
在了解反射前,我们先要知道一些相关知识
Class类
Class类的实例表示java应用运行时的类或接口,每个java类运行时都在JVM里表现为一个class对象,可通过类名.class、类型.getClass()、Class.forName("类名")等方法获取class对象。
类的加载流程可在另一篇文章查看。
定义
Java 反射(Reflection)是指在运行时动态地获取类的信息、调用方法、获取属性等,从而实现运行时的类型检查、动态代码生成、设置和操作类的信息等功能。(动态获取的信息以及动态调用对象)。有两个特点:
1、对于任意一个类,都能够知道这个类的所有属性和方法;
2、对于任意一个对象,都能够调用它的任意一个方法和属性;
通俗的说,反射就是把java类中的各种成分映射成一个个的Java对象。
一个类有:成员变量、方法、构造方法、包等等信息,利用反射技术可以对一个类进行解剖,把个个组成部分映射成一个个对象。
需要注意的是:
反射机制的使用可能会带来一些性能上的损失,因为它需要在运行时进行类型检查和方法调用。此外,反射机制还可能会导致安全漏洞,因为它可以执行任意代码。因此,在实际开发中,需要谨慎使用反射,并且根据具体情况选择是否使用反射。
反射的实现原理
基于java虚拟机的动态加载并依赖于 Class 类,java虚拟机在运行时动态的加载类,并生成对应的class对象,这个对象包含了类的所有信息,可通过class对象获取类的信息,进而实现对类的操作。
使用时大致可分为几个步骤:
反射获取类实例 -> 反射获取方法 -> 调用method.invoke()方法
1、获取 Class 对象:通过 Class.forName() 方法获取要反射的类的 Class 对象。
2、获取 Method 对象:通过getMethod() 等方法获取要调用的方法的 Method 对象。
3、调用方法:method.invoke() 方法调用该方法(最终是由jvm执行invoke0()执行),可获取返回值。
4、获取 Field 对象:通过getField() 等方法获取要访问的属性的 Field 对象。
5、设置属性值:通过 Field.setAccessible(true) 方法将属性设置为可访问。然后可以通过 Field.get(object) 方法获取该属性的值。
下面我们一步步分析一波。
Class类对象的获取
在类加载的时候,jvm会创建一个class对象,获取class对象的方式的主要有三种:
- 根据类名:类名.class
- 根据对象:对象.getClass()
- 根据全限定类名:Class.forName(全限定类名)
方法名 | 说明 |
forName() | (1)获取Class对象的一个引用,但引用的类还没有加载(该类的第一个对象没有生成)就加载了这个类。 (2)为了产生Class引用,调用forName()会立即就进行初始化。 |
Object-getClass() | 获取Class对象的一个引用,返回表示该对象的实际类型的Class引用。 |
getName() | 取全限定的类名(包括包名),即类的完整名字。 |
getSimpleName() | 获取类名(不包括包名) |
getCanonicalName() | 获取全限定的类名(包括包名),大多数情况下和getName一样 |
isInterface() | 判断Class对象是否是表示一个接口 |
getInterfaces() | 返回Class对象数组,表示Class对象所引用的类所实现的所有接口。 |
getSupercalss() | 返回Class对象,表示Class对象所引用的类所继承的直接基类。应用该方法可在运行时发现一个对象完整的继承结构。 |
newInstance() | 返回一个Oject对象,是实现“虚拟构造器”的一种途径。使用该方法创建的类,必须带有无参的构造器。 |
getFields() | 获得某个类的所有的公共(public)的字段,包括继承自父类的所有公共字段。 类似的还有getMethods和getConstructors。 |
getDeclaredFields | 获得某个类的自己声明的字段,即包括public、private和proteced,默认但是不包括父类声明的任何字段。类似的还有getDeclaredMethods和getDeclaredConstructors。 |
首先调用了 java.lang.Class 的静态方法forName()获取反射获取类信息,调用到new instance,
newInstance() 主要做了三件事:
- 权限检测,如果不通过直接抛出异常;
- 查找无参构造器,并将其缓存起来;
- 调用具体方法的无参构造方法,生成实例并返回;
然后是获取构造器的过程:
- 先获取所有的constructors, 然后通过进行参数类型比较;
- 找到匹配后,通过 ReflectionFactory copy一份constructor返回;
- 否则抛出 NoSuchMethodException;
Constructor类及其用法
Constructor 类表示的是Class 对象所表示的类的构造方法,利用它可以在运行时动态创建对象。
方法返回值 | 方法名称 | 方法说明 |
static Class | forName(String className) | 返回与带有给定字符串名的类或接口相关联的 Class 对象。 |
Constructor | getConstructor(Class... parameterTypes) | 返回指定参数类型、具有public访问权限的构造函数对象 |
Constructor[] | getConstructors() | 返回所有具有public访问权限的构造函数的Constructor对象数组 |
Constructor | getDeclaredConstructor(Class... parameterTypes) | 返回指定参数类型、所有声明的(包括private)构造函数对象 |
Constructor[] | getDeclaredConstructors() | 返回所有声明的(包括private)构造函数对象 |
T | newInstance() | 调用无参构造器创建此 Class 对象所表示的类的一个新实例。 |
方法返回值 | 方法名称 | 方法说明 |
Class | getDeclaringClass() | 返回 Class 对象,该对象表示声明由此 Constructor 对象表示的构造方法的类,其实就是返回真实类型(不包含参数) |
Type[] | getGenericParameterTypes() | 按照声明顺序返回一组 Type 对象,返回的就是 Constructor对象构造函数的形参类型。 |
String | getName() | 以字符串形式返回此构造方法的名称。 |
Class[] | getParameterTypes() | 按照声明顺序返回一组 Class 对象,即返回Constructor 对象所表示构造方法的形参类型 |
T | newInstance(Object... initargs) | 使用此 Constructor对象表示的构造函数来创建新实例 |
String | toGenericString() | 返回描述此 Constructor 的字符串,其中包括类型参数。 |
Field类及其用法
Field 表示Class对象所表示的类的成员变量,通过它可以在运行时动态修改成员变量的属性值(包含private)。
Field 类提供有关类或接口的单个字段的信息,以及对它的动态访问权限。
通过Class类的提供的方法来获取代表字段信息的Field对象
方法返回值 | 方法名称 | 方法说明 |
Field | getDeclaredField(String name) | 获取指定name名称的(包含private修饰的)字段,不包括继承的字段 |
Field[] | getDeclaredFields() | 获取Class对象所表示的类或接口的所有(包含private修饰的)字段,不包括继承的字段 |
Field | getField(String name) | 获取指定name名称、具有public修饰的字段,包含继承字段 |
Field[] | getFields() | 获取修饰符为public的字段,包含继承字段 |
方法返回值 | 方法名称 | 方法说明 |
void | set(Object obj, Object value) | 将指定对象变量上此 Field 对象表示的字段设置为指定的新值。 |
Object | get(Object obj) | 返回指定对象上此 Field 表示的字段的值 |
Class | getType() | 返回一个 Class 对象,它标识了此Field 对象所表示字段的声明类型。 |
boolean | isEnumConstant() | 如果此字段表示枚举类型的元素则返回 true;否则返回 false |
String | toGenericString() | 返回一个描述此 Field(包括其一般类型)的字符串 |
String | getName() | 返回此 Field 对象表示的字段的名称 |
Class | getDeclaringClass() | 返回表示类或接口的 Class 对象,该类或接口声明由此 Field 对象表示的字段 |
void | setAccessible(boolean flag) | 将此对象的 accessible 标志设置为指示的布尔值,即设置其可访问性 |
Method类及其用法
Method 表示Class对象所表示的类的成员方法,通过它可以动态调用对象的方法(包含private)。
Method 提供关于类或接口上单独某个方法(以及如何访问该方法)的信息。
方法返回值 | 方法名称 | 方法说明 |
Method | getDeclaredMethod(String name, Class... parameterTypes) | 返回一个指定参数的Method对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。 |
Method[] | getDeclaredMethods() | 返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。 |
Method | getMethod(String name, Class... parameterTypes) | 返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。 |
Method[] | getMethods() | 返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法。 |
方法返回值 | 方法名称 | 方法说明 |
Object | invoke(Object obj, Object... args) | 对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。 |
Class | getReturnType() | 返回一个 Class 对象,该对象描述了此 Method 对象所表示的方法的正式返回类型,即方法的返回类型 |
Type | getGenericReturnType() | 返回表示由此 Method 对象所表示方法的正式返回类型的 Type 对象,也是方法的返回类型。 |
Class[] | getParameterTypes() | 按照声明顺序返回 Class 对象的数组,这些对象描述了此 Method 对象所表示的方法的形参类型。即返回方法的参数类型组成的数组 |
Type[] | getGenericParameterTypes() | 按照声明顺序返回 Type 对象的数组,这些对象描述了此 Method 对象所表示的方法的形参类型的,也是返回方法的参数类型 |
String | getName() | 以 String 形式返回此 Method 对象表示的方法名称,即返回方法的名称 |
boolean | isVarArgs() | 判断方法是否带可变参数,如果将此方法声明为带有可变数量的参数,则返回 true;否则,返回 false。 |
String | toGenericString() | 返回描述此 Method 的字符串,包括类型参数。 |
获取方法也一样,
1. 获取所有方法列表;
2. 根据方法名称和方法列表,选出符合要求的方法;
3. 如果没有找到相应方法,抛出异常,否则返回对应方法;
后面调取invoke时,是通过 MethodAccessor 进行调用的,而 MethodAccessor 是个接口,在第一次时调用 acquireMethodAccessor() 进行新创建。
进行 ma.invoke(obj, args); 调用时,调用 DelegatingMethodAccessorImpl.invoke();
最后被委托到 NativeMethodAccessorImpl.invoke()
最后,再贴一张网络图
相关文章:

【五一创作】Java 反射
在了解反射前,我们先要知道一些相关知识 Class类 Class类的实例表示java应用运行时的类或接口,每个java类运行时都在JVM里表现为一个class对象,可通过类名.class、类型.getClass()、Class.forName("类名")等方法获取class对象。 …...

常见元件、封装、尺寸、表面处理等
参考:https://www.bilibili.com/read/cv11024927?fromsearch&spm_id_from333.337.0.0 参考:https://www.bilibili.com/read/cv18413169?fromsearch&spm_id_from333.337.0.0 目录 通孔插件(THT)和表面贴装(SMT)技术封装类型SOP/SOIC封装DIP封装…...

作为一名8年测试工程师,因为偷偷接私活被····
接私活 对程序员这个圈子来说是一个既公开又隐私的话题,不说全部,应该大多数程序员都有过想要接私活的想法,当然,也有部分得道成仙的不主张接私活。但是很少有人在公开场合讨论私活的问题,似乎都在避嫌。就跟有人下班后…...

前端面试八股文
1、HTTP和HTTPS 1.1、http和https的基本概念 http: 是一个客户端和服务器端请求和应答的标准(TCP),用于从 WWW 服务器传输超文本到本地浏览器的超文本传输协议。 https: 是以安全为目标的 HTTP 通道,即 HTTP 下 加入 SS…...

[创新工具和方法论]-02- DOE实验设计步骤
文章目录 1.DOE设计1.1 基于OFAT的传统实验设计:1.2 基于DoE的现代实验设计:1.3 DOE和OFAT的比较1.4 如何利用好DOE1.4.1 规划1.4.2 筛选1.4.3 表征1.4.4 优化1.4.5 确认 2. 步骤2.1陈述实际的问题和实验的目的2.2因果链分析,提取重要的因子2.3选择Y的响…...

XXL-JOB分布式任务调度平台搭建以及和SpringBoot整合应用
1 前言 XXL-JOB 是一个轻量级分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用。 可以前往 Gitee 地址进行下载使用: https://gitee.com/xuxueli0323/xxl-job.g…...

【LeetCode】236. 二叉树的最近公共祖先
1.问题 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是…...

STM32F4 HAL库使用DMA进行ADC采样实时发送波形到串口显示(包含傅里叶变换)
1.总体逻辑 按下STM32F4的KEY0按键,通过外部中断的方式对按键进行检测,然后开启一次带DMA的固定点数的ADC采集,采集完成后在DMA的中断发送采集到的数据,然后清空数据区准备下一次的按键中断。电脑接受到串口数据后对数据进行简单…...

ChatGPT 平替天花板:HuggingFace 版 ChatGPT 来了,无需魔法无需等待直接起飞 ~
文章目录 ChatGPT 平替天花板:HuggingFace 版 ChatGPT 来了,无需魔法无需等待直接起飞 ~HuggingFace 简介HuggingChat 登场展望 ChatGPT 平替天花板:HuggingFace 版 ChatGPT 来了,无需魔法无需等待直接起飞 ~ 二话不说上链接 htt…...

桐乡学会计实操—小规模纳税人征收率的汇总帖来啦!
上元会计—会计实操—小规模纳税人征收率的汇总帖来啦!一文了解 小规模纳税人发生应税行为适用简易计税方法计税。那么小规模纳税人增值税的征收率到底有几档?很多人以为小规模纳税人适用的征收率只有3%,但是有没有其他征收率呢,…...

权威学者、企业CFO荟聚上海国家会计学院,共探「智能会计 价值财务」
4月21日,由用友主办的「智能会计 价值财务」2023企业数智化财务创新峰会在上海国家会计学院圆满举办。学院权威教授、业内专家与来自央国企、行业领先企业的财务先锋,线下云端共聚一堂,数万人共探大型企业财务数智化的全新价值主张。 会议伊始…...

根据cadence设计图学习硬件知识day06 了解一些电源转化芯片和 稳压器 和 开关芯片
1. TPL920 (高精度线性稳压器) 1.1.TPL920 介绍 TPL920系列产品是2A大电流、6μVRMS低噪声、高PSRR、高精度线性稳压器,通常具有在2A负载条件下的110 mV超低电压降。这TPL920系列产品同时支持固定输出电压范围从0.8伏到3.95伏,输出电压可调范围为0.8V至…...

简单理解内存分页机制
文章目录 1.CPU寻址方式2.段式内存访问的缺点3.80386两级页表4.PAE三级页表5.x64四级页表6.虚拟内存 思考一个问题:如果没有这样的分页机制时应用程序是怎么访问物理内存地址? 1.CPU寻址方式 Effective Address Base (Index * Scale) Displacement …...

如何提高三维模型OSGB格式转换3DTILES的转换速度和数据质量
如何提高三维模型OSGB格式转换3DTILES的转换速度和数据质量 提高三维模型从OSGB格式转换为3DTILES格式的转换速度和数据质量,可以从以下几个方面进行优化: 1、选用高效的转换工具:选择高效的转换工具是提高转换速度和数据质量的关键。目前市…...

智现未来面试(部分)
容器化有哪些好处和坏处? 部分Answer by newBing:容器化的好处有很多,包括: 可移植性:应用程序容器会创建一个从主机操作系统提取出来的可执行软件包,使得应用程序可以在不同的环境中运行,而不需要重新配置…...

最值得学的编程语言是哪个?
如果让我推荐的话,我肯定首选是python啦! 编程语言是一个计算机的概念,在我们有了计算机以后,想让它帮助我们做事情,就要通过计算机语言和它进行对话、交互,计算机语言能够被计算机所执行,完成…...

研读Rust圣经解析——Rust learn-16(高级trait,宏)
研读Rust圣经解析——Rust learn-16(高级trait,宏) 高级trait关联类型Type为什么不用泛型而是Type 运算符重载(重要等级不高)重名方法消除歧义never typecontinue 的值是 ! 返回闭包 宏自定义宏(声明宏&…...

html,Javascript,css前端面试题汇总免费
html,Javascript,css前端面试题汇总免费 下载地址: html,Javascript,css前端面试题汇总免费.docx下载—无极低码 一,html与css 1,页面导入样式,使用link与import有什么区别? (1) 从属关系:link是html标签…...

HFSS—RCS测量
RCS 引言单位仿真步骤新建工程建立待测物体模型设置边界条件设置入射波添加分析可行性分析和仿真结果输入引言 雷达散射截面是隐身技术中的重要指标。用于衡量目标物体在电磁波照射下产生回波强度,也就是散射的强度。 一方面,雷萨散射截面可以用入射电磁场的强度和散射电磁场…...

QUARTZ 石英框架
QUARTZ 石英框架 1.Quartz的概念 Quartz就是一个基于Java实现的任务调度框架,用于执行你想要执行的任何任务。 Quartz是OpenSymphony开源组织在Job scheduling(定时调度)领域的开源项目,它可以与J2EE和J2SE应用程序相结合也可以…...

基于centos7:Harbor-2.7.2部署和安装教程
基于centos7:Harbor-2.7.2部署和安装教程 1、软件资源介绍 Harbor是VMware公司开源的企业级DockerRegistry项目,项目地址为https://github.com/vmware/harbor。其目标是帮助用户迅速搭建一个企业级的Dockerregistry服务。它以Docker公司开源的registry…...

Windows上使用CLion配置OpenCV环境,亲测可用的方法(一)
一、Windows上使用CLion配置OpenCV环境,亲测可用的方法: Windows上使用CLion配置OpenCV环境 教程里的配置: widnows 10 clion 2022.1.1 mingw 8.1.0 opencv 4.5.5 Cmake3.21.1 我自己的配置: widnows 10 clion 2022.2.5 mingw 8.…...

代码随想录算法训练营第四十三天
代码随想录算法训练营第四十三天| 1049. 最后一块石头的重量 II,494. 目标和,474. 一和零 1049. 最后一块石头的重量 II494. 目标和474. 一和零 1049. 最后一块石头的重量 II 题目链接:最后一块石头的重量 II 重点: 本题其实就是…...

如何在 Mac 和 Windows 上恢复未保存或删除的 PDF
Adobe Acrobat PDF 是一种常用格式。我们可能会在不同的 PDF 编辑器中编辑和保存 PDF 文件。但是,如果不保存 PDF 文件或不小心将其删除,那将是一种令人不安的体验。 保持冷静!首先,尽可能多地停止运行应用程序,这样它…...

windows开机不自动挂载磁盘的方法
本人的电脑系统为win11 写作时间20230430 开机不挂载某块磁盘的理由 1.本人电脑上有个仓库盘是机械硬盘,并不是每次开机都要用到,开机不挂载也许有利于增加数据盘的寿命 2.挂载了数据盘,有时候打开文件页面会比较慢,不够丝滑 …...

5 款 AI 老照片修复工具的横向比较
在大语言模型和各类 AI 应用日新月异的今天,我终于下定决心,趁着老照片们还没有完全发黄褪色、受潮粘连抑或损坏遗失,将上一代人实体相册里的纸质胶卷照片全部数字化,并进行一次彻底的 AI 修复,好让这些珍贵的记忆能更…...

2023企业服务的关键词:做强平台底座
作者 | 曾响铃 文 | 响铃说 4月下旬,软件行业相关的大会紧锣密鼓地开了好几场,不仅有政府主办的2023中国国际软件发展大会、中国软件创新发展大会,也有用友、浪潮等服务商举办的品牌活动,让软件业的话题一直保持热度。 以用友为…...

【Linux基本指令和权限(1)】
本文思维导图: 文章目录 一、Linux操作的特点二、使用指令从Xhell登录云服务器三、基本指令1.ls指令2. pwd指令:3.cd指令4. touch指令5. rm指令 写在最后 Linux是一个操作系统,操作系统是一款做软硬件管理的软件。 一、Linux操作的特点 Li…...

虹科新品 | 用于医疗应用的压力和气体流量传感器
ES Systems在创新MEMS方面拥有丰富的经验,设计了高质量和高性能的气体流量和压力传感器,由于其技术规格,出色的可靠性和有竞争力的价格,这些传感器在竞争产品中具有独特的品质。 Part.01 应用背景 众所周知,在医疗领域…...

原生小程序如何使用pdf.js实现查看pdf,以及关键词检索高亮
1.下载pdf.js库文件 前往 pdf.js 的 官网 下载库文件,下哪个版本都可以,后者适用于旧版浏览器,所以我下载的是后者 下载完成后,因为微信小程序打包的限制,我将库文件放到项目的后台系统了,在h5端处理会比在…...