【从零到Offer】反射那些事

什么是反射?

​ 反射简单来说,就是在代码运行期间,通过动态指定任意一个类,从而构建对象,并了解该类的成员变量和方法,甚至可以调用任意一个对象的属性和方法。以String对象为例子,传统构造方式和反射的实现方式如下:

//new 构造方法
String s = new String();

//反射
Class<?> forName = Class.forName("java.lang.String");

​ 从代码中不难看到,第一种通过构造函数构造出来的对象,是在编译前就确定好了的。由此编译程序可以明确的知道当前操作的类是哪个,包含哪些属性、有什么方法。

​ 然而对于第二种实现方式来说,通过反射映射出来的对象完全取决于你给定的字符串是什么。如果我们将这个字符串抽取成配置,那么生产出来的对象自然就会是动态的了。

为什么需要反射?

​ 那么,你可能想问了,好好的new 对象不好吗?为啥还要设计出来一个反射呀?他有什么好处呢?其实,直白来讲,反射牺牲掉了安全、效率,更多的是为了提供更多的灵活性。

​ 假设当前你所负责的代码,要处理两个不同的对象,那么为了完成工作,你可能需要通过多次的if-else判断、处理,哪怕两个对象内的字段名称、类型都是一样的,受限于编译器的限制,你也没法共用同一段代码。

if (i==1){
    // ....执行针对ObjectA的处理方法
    ObjectA o = (ObjectA) input;
    o.setData(xxx);
} else if (i==2) {
    // ....执行针对ObjectB的处理方法
    ObjectB o = (ObjectB) input; 
    o.setData(xxx);
}

​ 但是如果借助于反射,我们就可以将代码充分利用起来,从而最大程度减少代码开发,提升日常效率

if (i==1){
    // ....执行针对ObjectA的处理方法
    Class<?> forName = Class.forName("com.example.demo.base.dto.ObjectA");
} else if (i==2) {
    // ....执行针对ObjectB的处理方法
    Class<?> forName = Class.forName("com.example.demo.base.dto.ObjectB");
}       
Object o = (Object) input;

//同一段处理逻辑,无需再写两次
Field resultStr = forName.getDeclaredField("resultStr");
resultStr.set(o, "1");

​ 在日常代码开发中,也有很多组件无形之中使用到了反射的设计原理。如我们熟悉的Bean拷贝组件BeanUtils,其方便的实现对象间的拷贝逻辑就是基于反射实现的。

如何实现反射?

​ 首先我们知道,我们日常所编写的代码,最后都是会变成.java格式的文档。而.java格式的文档是不可能被机器直接执行的,因为机器只能够看懂二进制的文件。

​ 因此,从.java文件到jvm中可执行的对象,它其实经过了如下的过程:

​ 首先,我们的.java文件会被编译器编译成.class文件,对于每个.class文件,又会被JVM调用类加载的方式,加载到JVM内存中并生成为一个Class对象。这里我们简单看一下Class对象长什么模样:

​ 可以看到Class类对象中包含了许多用于描述类的属性,如类名、所使用的类加载器等。包括通过Class类对象也可以搜索到当前类的构造器、特定的属性域等。

​ 而且对于这个特殊的类来说,我们是不能够对其进行初始化的。可以看到,它只提供了一个私有的构造方法,且需要传入的是类加载器。而且在方法的注释上,也很明确的标注出来,这个构造方法只是提供给JVM创建实例用的,不应该作为默认的类构造器。

​ 通常来说,如果我们需要调用一个Class对象,那么通常只能通过以下的方式:

Class<?> clz = Class.forName("xxx.class");
Class<?> clz = Object.class;
Class<?> clz = Object.getClass();

​ 而且通过不断的往下搜索,我们也可以看到,这个方法的底层实现是通过native方法实现的。(部分java代码通过c等语言实现的,此时会被标记为native方法,是不可以直接调用的。)

​ 虽然我们不能调用,但是本质上这个方法就是通过类加载器获取的过程。了解了这些之后,我们再将咱们的日常使用java类的过程梳理一下:

​ 所以可以看到,反射本质上,维护实例的流程同正常的new创建对象并无过多的差异,他们本质都是基于class对象生成的实例,只是通过new的方式,用户是能够明确知道所需要使用的类的,因此编译器也能方便的对代码进行检查。

​ 而使用反射的方式,则是利用了Class对象,创造出了编码的灵活性。本质思想就是:“你可以是任何类,但我的逻辑对任何类都适配。”通过这样的牺牲掉一些安全性,从而获得编码的灵活性。

参考文献

学习java应该如何理解反射?

java的反射到底是有什么用处?怎么用?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/37767.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

计算机网络 - http协议 与 https协议(2)

前言 本篇介绍了构造http请求的的五种方式&#xff0c;简单的使用postman构造http请求&#xff0c;进一步了解https, 学习https的加密过程&#xff0c;了解对称密钥与非对称密钥对于加密是如何进行的&#xff0c;如有错误&#xff0c;请在评论区指正&#xff0c;让我们一起交流…

SPEC CPU 2006 在 CentOS 5.0 x86_64 古老系统测试【3】静态编译 invalid run

上篇 SPEC CPU 2006 在 CentOS 5.0 x86_64 古老系统测试【2】_hkNaruto的博客-CSDN博客 修改gcc41.cfg&#xff0c;全部添加上-static 测试指令 runspec -c gcc41.cfg -T all -n 3 -r 1 -I -i ref all 结果&#xff1a;正常运行并生成报告 invalid run Invalid SPEC CFP2006…

自学网络安全(成为黑客)

一、前言 黑客这个名字一直是伴随着互联网发展而来&#xff0c;给大家的第一印象就是很酷&#xff0c;而且技术精湛&#xff0c;在网络世界里无所不能。目前几乎所有的公司企业甚至国家相关部门都会争相高薪聘请技术精湛的黑客作为互联网机构的安全卫士&#xff0c;所以黑客也…

rapid_latex_ocr: 更快更好用的公式图像转latex工具

Rapid Latex OCR rapid_latex_ocr是一个将公式图像转为latex格式的工具。仓库中的推理代码来自修改自LaTeX-OCR&#xff0c;模型已经全部转为ONNX格式&#xff0c;并对推理代码做了精简&#xff0c;推理速度更快&#xff0c;更容易部署。仓库只有基于ONNXRuntime或者OpenVINO推…

【Linux】基础开发工具——make

文章目录 前言&#xff1a;一、认识make和makefile二、依赖关系和依赖方法三、make工作原理 前言&#xff1a; 上一期分享了在Linux下编译源代码的两个工具&#xff0c;gcc和g。每次编译源代码&#xff0c;都要输入一串很长的指令&#xff0c;这个过程显然是十分复杂&#xff…

【Go|第8期】Lorca读取HTML的三种方式

日期&#xff1a;2023年7月16日 作者&#xff1a;Commas 签名&#xff1a;(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释&#xff1a;如果您觉得有所帮助&#xff0c;帮忙点个赞&#xff0c;也可以关注我&#xff0c;我们一起成长&#xff1b;如果有不对的地方&#xf…

天天刷题-->LeetCode(最长回文子串)

个人名片&#xff1a; &#x1f405;作者简介&#xff1a;一名大二在校生&#xff0c;热爱生活&#xff0c;爱好敲码&#xff01; \ &#x1f485;个人主页 &#x1f947;&#xff1a;holy-wangle ➡系列内容&#xff1a; &#x1f5bc;️ tkinter前端窗口界面创建与优化 &…

JVM内存结构——前言

前提 1. 认识JVM&#xff0c;什么是JVM 简单来说&#xff0c;就是java程序的运行环境&#xff08;java二进制字节码的运行环境&#xff09; 1.1 JVM &#xff08;java虚拟机&#xff09;的好处 &#xff1a; 一次编写&#xff0c;到处运行的机制 &#xff08;因为java语言是跨…

残差网络(ResNet) -深度学习(Residual Networks (ResNet) – Deep Learning)

在第一个基于cnn的架构(AlexNet)赢得ImageNet 2012比赛之后&#xff0c;每个随后的获胜架构都在深度神经网络中使用更多的层来降低错误率。这适用于较少的层数&#xff0c;但当我们增加层数时&#xff0c;深度学习中会出现一个常见的问题&#xff0c;称为消失/爆炸梯度。这会导…

可靠的手机问题修复工具分享 - 修复各种 Android 系统问题

一般来说&#xff0c;安卓手机都可以流畅运行。但不幸的是&#xff0c;有时您的Android手机可能无法正常运行&#xff0c;例如无响应、突然重启等。在这种情况下&#xff0c;您将需要Android手机维修软件。这些 Android 修复工具可以帮助您轻松解决此类问题&#xff0c;并还给您…

5.3 Python高级特性之-列表生成式、生成器、迭代器

一、 列表生成式 是Python内置的非常简单却强大的可以用来创建list的生成式 具体可根据如下案例理解&#xff0c;且代码也是可用的""" 1、 生成[0,1,2,3,4,5,6]这样列表 """ print(list(range(0, 7))) """ 2、 生成[0&#xff0…

【数据结构】树与二叉树(上)

目录 前言&#xff1a; 一、树&#xff1a; 1.树的概念&#xff1a; 2.树的相关概念&#xff1a; 3.树的表示&#xff1a; 4.书的实际使用场景&#xff1a; 二、二叉树&#xff1a; 1.二叉树的概念&#xff1a; 2.两种特殊二叉树&#xff1a; ①.满二叉树&#xff1a;…

在Vue种使用Vant框架

第一步&#xff1a;打开Vant框架地址 https://vant-contrib.gitee.io/vant/v2/#/zh-CN/home 第二步&#xff1a; 安装 第三步&#xff1a;引入&#xff08;我这里使用的是按需导入&#xff09; 执行命令&#xff1a; npm i babel-plugin-import -D ①&#xff1a;src下创建个…

Oracle解析JSON字符串

Oracle解析JSON字符串 假设某个字段存储的JSON字符串&#xff0c;我们不想查出来后通过一些常见的编程语言处理&#xff08;JSON.parse()或者是JSONObject.parseObject()等&#xff09;&#xff0c;想直接在数据库上处理&#xff0c;又该如何书写呢&#xff1f; 其实在ORACLE中…

小程序api的promise化

小程序根目录cmd运行安装命令 npm install --save miniprogram-api-promise1.0.4 安装完成之后先到根目录中删除miniprogram_npm文件夹(不删除构建npm时可能会出现问题) 删除之后再在工具中点击构建npm 构建成功之后会看到根目录中重新出现了miniprogram_npm文件夹 在app.j…

RNN LSTM

参考资料&#xff1a; 《机器学习2022》李宏毅史上最详细循环神经网络讲解&#xff08;RNN/LSTM/GRU&#xff09; - 知乎 (zhihu.com) LSTM如何来避免梯度弥散和梯度爆炸&#xff1f; - 知乎 (zhihu.com) 1 RNN 的结构 首先考虑这样一个 slot filling 问题&#xff1a; 注意…

(简单)剑指Offer 21. 调整数组顺序使奇数位于偶数前面 Java

记数组nums的长度为n。从先nums左侧开始遍历&#xff0c;如果遇到的是奇数&#xff0c;就表示这个元素已经调整完成&#xff0c;继续从左往右遍历&#xff0c;直到遇到一个偶数。然后从nums右侧开始遍历&#xff0c;如果遇到的是偶数&#xff0c;就表示这个元素已经调整完成了&…

[JVM] 1. 初步认识JVM

核心思想&#xff1a; “Write Once, Run anywhere”. 各种语言通过编译器转换成字节码文件&#xff0c;在JVM上运行。 一、Java虚拟机 Java虚拟机是一台执行Java字节码的虚拟计算机&#xff0c;它拥有独立的运行机制&#xff0c;其运行的Java字节码也未必由Java语言编译而成…

辅助驾驶功能开发-功能规范篇(27)-2-导航式巡航辅助NCA

书接上回 2.2.2.3规划控制模块 2.2.2.3.1.全局导航规划 当用户输入导航终点时&#xff0c;全局导航规划模块会根据高精地图的覆盖区域将全局导航路径分为ICA,NCA可用段。实现ICA/NCA功能的划分及自动升降级。 当自车未按照导航路径行驶时(如未使出指定匝道&#xff0c;路口未…

折叠屏手机的屏幕,华为Mate X3给出了一份“内外兼修”的解决方案

说起折叠屏手机&#xff0c;屏幕一直都是这个领域的重头戏&#xff0c;很多人都对折叠屏手机有一种刻板印象&#xff0c;那就是脆弱。但是&#xff0c;3月份华为最新推出的Mate X3可以说是非常的亮眼&#xff0c;在内外屏幕、水滴铰链、影像系统等多个核心部件的全方位提升&…