关于Java 反射的简单易懂的介绍
目录
#0.总览
#1. 类的反射
①介绍
②获取
③作用
获取构造函数:
创建实例:
字段操作:
方法操作:
获取修饰符:
#2.总结
#0.总览
反射,官方是这样介绍它的:
Reflection is a feature in the Java programming language. It allows an executing Java program to examine or "introspect" upon itself, and manipulate internal properties of the program.
翻译过来就是:反射是 Java 编程语言中的一项功能。它允许正在执行的 Java 程序检查或“内省”自身,并作程序的内部属性。
再翻译成人话就是:反射可以让程序可以把本身的各种方法,参数当作变量来使用。
为什么翻译成“反射”?因为这个过程就像是照镜子:程序通过照镜子知道自己有什么方法和参数。
详细的说,有:
- 获取类的信息(类名、方法、字段、构造方法等)。
- 创建类的实例。
- 调用类的方法、修改字段的值。
- 动态地加载类和进行方法调用。
- 与代理息息相关
#1. 类的反射
①介绍
首先得介绍一下Class类
Class类是反射的核心部分
Class类和真实的类对象不是一个东西!Class类只是包含了对应类关于其涉及反射的一系列操作的类。每个类都会有属于自己的Class对象:
列如 String.class Integer.class等
尝试输出:
System.out.println(String.class);
会得到 class java.lang.String
这是类的全限定类名,可以看成是类的标识。
②获取
通过一些方法,我们能获得一个类的Class对象:
Class ex1 = Class.forName("java.lang.String");
Class ex2 = String.class;
String string = new String();
Class ex3 = string.getClass();
那获取到Class类有什么用呢?
③作用
获取构造函数:
拿这个类来举例:
public class Temp {public int a;public int b;private int c = 10;public Temp() {}public Temp(int a) {this.a = a;}private Temp(int a, int b) {this.a = a;this.b = b;}public void sing(){System.out.println("ahhhhhh!");}private void dance(){System.out.println("haaaaaa!");}
}
Class ex = Temp.class;ex.getConstructor(); ex.getConstructor(int.class);
这会获得其一个指定的公共构造方法,注意!括号中的参数要这样写上对应的Class类才能获取到!
ex.getDeclaredConstructor();则可以获取到所有构造方法
相对的,Constructor<?>[] constructors = ex.getConstructors();则会获取所有公用构造方法
getDeclaredConstructors同理
创建实例:
Constructor constructor = ex.getConstructor(int.class);
Temp obj = (Temp) constructor.newInstance( 30);这样就根据指定的构造方法创建出了一个指定的实例
字段操作:
Temp obj = (Temp) constructor.newInstance( 30);
Field field = ex.getField("a");
System.out.println(field);
int value = field.getInt(obj);
System.out.println(value);这里会输出 30
注意!除了getInt还有getchar等对应基本数据类型,其他的统一为get()
但其实get()也能处理基本数据类型
格式为 Field.get(已实例化的对象)
对于私有变量,无独有偶:getDeclaredField(“c”)即可
但是只能System.out.println(field);,即获取全限定字段名,无法获得具体值!
解决方法在下:
但是对于字段修改:
如果是公共字段:
field.set(obj, 666);
就可以完成修改
私有字段是无法修改的!
必须先取消限制:
field.setAccessible(true);
这样才可以让私有字段像公共字段一样可以被查看,修改。
方法操作:
对于方法,有了前面的铺垫则简单得多:
对于公共方法:
Class ex = Temp.class;
Constructor constructor = ex.getConstructor();
Temp obj = (Temp) constructor.newInstance();Method greetMethod = ex.getMethod("sing");
greetMethod.invoke(obj);这样就成功执行了sing方法
如果想要获取所有方法
Method[] methods = ex.getMethods();即可
但是必须要有一个已经实例化的对象obj才能正常的通过invoke操作来执行方法!
实际上,执行的方法实际上是已经实例化的obj里面对应的方法!
对于一些函数,可能名字相同但是参数不同,可以仿照构造函数那样加以区分:
Method greetMethod = ex.getMethod("sing",int.class);
Method greetMethod = ex.getMethod("sing",String.class);类似这样来区分
对于私有方法:
和字段一模一样
在方法名上加上Declared
如getDeclaredMethod,getDeclaredMethods
然后得加上greetMethod.setAccessible(true);才能正常操作
获取修饰符:
可以通过类似于:
int x = greetMethod.getModifiers();
来获取任何方法/字段的修饰符,也许你会疑惑为什么是int类型,原因是JAVA中的确是用数字来存储修饰符的,比如说:
public=1,private=2,protected=3,default=4
获取接口:
获取接口相对来说非常简单:
Class<?>[] interfaces = ex.getInterfaces();
这样便可获取所有ex类所实现的接口
获取注释:
Annotation[] annotations = ex.getAnnotations();
这样就获取了ex类所有的注释内容!
如果想获取方法的注释也非常简单:
Annotation[] annotations = ex.getMethod("xxx").getAnnotations();
(提一句,对于每个注释都是一个单独的类型,假如你需要@CY注释,改成
CY annotation = ex.getMethod("xxx").getAnnotation();也行)接下来想要提取注释变量什么的就随你了
这种方法可以用来实现公共字段补全
#2.总结
归功于反射机制,程序得以对本身进行修改而不依赖于人工修改,也提供了更多的灵活性,
更是为实现动态代理提供了可能。
(我也写了一篇介绍代理的文章,欢迎捧场!)
你也许会发现,这种获取参数,接口,方法是不是很熟悉?是不是我们用的IDE就有点用了这种方式的意思?不然为什么我们写了一个函数就能提示要放什么参数进去?
这的确很像,但实际上IDE是会实时构造一个抽象语法树(AST),它是代码结构的表示。这使得 IDE 能够理解类、方法、字段和参数的存在及其类型。
尽管如此,反射非常重要,java,spring框架里面反射无处不在,
但是,反射的性能开销很大,因为它要在运行中实时解析类,方法,字段,这些原本是在编译时完成的,而且反射无法被编译器进行优化!
所以谨慎使用!
相关文章:
关于Java 反射的简单易懂的介绍
目录 #0.总览 #1. 类的反射 ①介绍 ②获取 ③作用 获取构造函数: 创建实例: 字段操作: 方法操作: 获取修饰符: #2.总结 #0.总览 反射,官方是这样介绍它的: Reflection is a …...
市场趋势中突破确认的多维度判断方法
波动率突破策略是众多交易者广泛采用的重要交易策略之一。而在这一策略中,准确判断突破是否有效,是决定交易成败的关键环节。仅仅依据单一因素来确认突破,往往会使交易者陷入误判的困境,导致不必要的损失。因此,采用多…...
网络空间安全(2)应用程序安全
前言 应用程序安全(Application Security,简称AppSec)是一个综合性的概念,它涵盖了应用程序从开发到部署,再到后续维护的整个过程中的安全措施。 一、定义与重要性 定义:应用程序安全是指识别和修复应用程序…...
【MyBatis】CRUD、配置解析、ResultMap、分页实现
目录标题 1、Mybatis简介1.1、什么是MyBatis1.2、持久化1.3、持久层1.4、为什么需要MybatisMyBatis的优点 2.1、代码演示搭建实验数据库导入MyBatis相关 jar 包 03、CRUD操作3.1、namespace3.2、select3.3、insert3.4、update3.5、delete 04、MyBatis配置解析4、配置解析4.3、m…...
Linux系统编程之高级信号处理
概述 在前一篇文章中,我们介绍了signal函数、sigaction函数等基本的信号处理方法。在本篇中,我们将介绍信号处理的一些高级用法,包括:阻塞与解除阻塞、定时器等。 阻塞与解除阻塞 有时候,我们不希望某个信号立即被处理…...
深度学习驱动的车牌识别:技术演进与未来挑战
一、引言 1.1 研究背景 在当今社会,智能交通系统的发展日益重要,而车牌识别作为其关键组成部分,发挥着至关重要的作用。车牌识别技术广泛应用于交通管理、停车场管理、安防监控等领域。在交通管理中,它可以用于车辆识别、交通违…...
钉钉快捷免登录 通过浏览器打开第三方系统,
一、钉钉内跳转至浏览器的实现 使用钉钉JSAPI的跳转接口 在钉钉内通过dd.biz.navigation.openLink方法强制在系统浏览器中打开链接。此方法需在钉钉开发者后台配置应用权限,确保应用具备调用该API的资格37。 示例代码: dd.ready(() > {dd.biz.navigat…...
力扣——杨辉三角
题目链接: 链接 题目描述: 思路: 直接找规律,按照数学的思路来 每一行的列最大索引 < 行索引 实现代码: class Solution {public List<List<Integer>> generate(int numRows) {List<List<In…...
stm32108键C-B全调性_动态可视化乐谱钢琴
108键全调性钢琴 一 基本介绍1 项目简介2 实现方式3 项目构成 二 实现过程0 前置基本外设驱动1 声音控制2 乐谱录入&基础乐理3 点阵屏谱点动态刷新4 项目交互控制5 录入新曲子过程 三 展示,与链接视频地址1 主要功能函数一览2 下载链接3 视频效果 一 基本介绍 …...
mysql之规则优化器RBO
文章目录 MySQL 基于规则的优化 (RBO):RBO 的核心思想:模式匹配与规则应用RBO 的主要优化规则查询重写 (Query Rewrite) / 查询转换 (Query Transformation)子查询优化 (Subquery Optimization) - RBO 的重中之重非相关子查询 (Non-Correlated Subquery)…...
MySQL数据库——表的约束
1.空属性(null/not null) 两个值:null(默认的)和not null(不为空) 数据库默认字段基本都是字段为空,但是实际开发时,尽可能保证字段不为空,因为数据为空没办法…...
vue2.x 中子组件向父组件传递数据主要通过 $emit 方法触发自定义事件方式实现
在 Vue 2.x 中,子组件向父组件传递数据主要通过 自定义事件 的方式实现。具体步骤如下: 1. 子组件通过 $emit 触发事件 子组件可以使用 $emit 方法触发一个自定义事件,并将数据作为参数传递给父组件。 语法: this.$emit(事件名…...
洛谷 P1102 A-B 数对(详解)c++
题目链接:P1102 A-B 数对 - 洛谷 1.题目分析 2.算法原理 解法一:暴力 - 两层for循环 因为这道题需要你在数组中找出来两个数,让这两个数的差等于定值C就可以了,一层for循环枚举A第二层for循环枚举B,求一下看是否等于…...
python用 PythonNet 从 Python 调用 WPF 类库 UI 用XAML
pythonnet 是pythonhe.net通用的神器不多介绍了. 这次这基本上跟python没有关系了. 和winform一样先导包 import clr clr.AddReference("PresentationFramework.Classic, Version3.0.0.0, Cultureneutral, PublicKeyToken31bf3856ad364e35") clr.AddReference(&…...
C++——list模拟实现
目录 前言 一、list的结构 二、默认成员函数 构造函数 析构函数 clear 拷贝构造 赋值重载 swap 三、容量相关 empty size 四、数据访问 front/back 五、普通迭代器 begin/end 六、const迭代器 begin/end 七、插入数据 insert push_back push_front 八、…...
YOLOv11-ultralytics-8.3.67部分代码阅读笔记-utils.py
utils.py ultralytics\data\utils.py 目录 utils.py 1.所需的库和模块 2.def img2label_paths(img_paths): 3.def get_hash(paths): 4.def exif_size(img: Image.Image): 5.def verify_image(args): 6.def verify_image_label(args): 7.def visualize_image_ann…...
Linux 内核 RDMA CM 模块分析:drivers/infiniband/core/cma.c
一、引言 随着高性能计算和大数据处理需求的不断增长,远程直接内存访问(RDMA)技术在数据中心和高性能计算领域得到了广泛应用。RDMA 允许数据直接在不同系统的内存之间传输,而无需经过 CPU 和操作系统的干预,从而显著提高了数据传输效率和系统性能。Linux 内核中的 RDMA …...
Flask flash() 消息示例
目录 安装 Flask 入门:Flask flash() 基本示例 进阶:使用 Flask-WTF Flash 登录结果消息 详解:get_flashed_messages() 详解:flash() 消息的完整生命周期 Flask 提供 flash() 用于向 用户传递临时消息,通常用于: • 表单提交成功或失败 • 用户登录、注册、退出提…...
ImGui 学习笔记(三)—— 隐藏主窗口窗口关闭检测
ImGui 的主窗口是平台窗口,默认是可见的,这会影响视觉效果。那么怎么隐藏 ImGui 的主窗口呢? 这很简单,但是需要针对后端做一些修改。 本文仅介绍在 glfwopengl3 和 win32dx11 两种实现上如何修改。 在 win32dx11 实现上&#…...
ubuntu磁盘清理垃圾文件
大头文件排查 #先查看是否是内存满了,USER 很高即是满了 du -f#抓大头思想,优先删除大文件#查看文件目录 内存占用量并排序,不断文件递归下去 du --max-depth1 -h /home/ -h | sort du --max-depth1 -h /home/big/ -h | sort 缓存文件清理…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验
系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...
初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...
MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用
文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...
LUA+Reids实现库存秒杀预扣减 记录流水 以及自己的思考
目录 lua脚本 记录流水 记录流水的作用 流水什么时候删除 我们在做库存扣减的时候,显示基于Lua脚本和Redis实现的预扣减 这样可以在秒杀扣减的时候保证操作的原子性和高效性 lua脚本 // ... 已有代码 ...Overridepublic InventoryResponse decrease(Inventor…...
