反射讲解(有图有真相)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、反射是什么?
  • 二、反射有啥好处?
      • 1. 没反射
      • 2. 有反射
  • 三、反射的常用方法
      • 1. 获取 Class 对象:
      • 2. 获取类的构造方法:
      • 3. 获取类的字段信息:
      • 4. 获取类的方法信息:
      • 5. 创建对象和调用方法:
  • 四、总结


前言

提示:小车车🚗准备出发。。。。。

今天咋们来搂一搂反射是啥?有啥用?各位请上车,系好安全带。。。。


提示:路途颠簸系好安全带!!!!

一、反射是什么?

当我们写Java程序时,通常情况下,我们会在编译时确定所有的类、方法和属性。但是有些时候,我们希望在程序运行时动态地获取和操作类的信息,这就是反射。

反射是指在运行时动态地获取类的信息并操作类的成员。

在Java中,每个类都有一个对应的Class对象,这个对象包含了类的信息,如类的名称、属性、方法等。反射机制允许我们在运行时获取这个Class对象,进而获取和操作类的信息。

⚠️这里给大家提个小问题:为什么Java只能在程序运行阶段才能动态获取类的信息并操作类的成员呢?

原因如下:

  1. 类加载: 在 Java 程序运行时,JVM 负责加载类的字节码文件。这个过程称为类加载。类加载器将字节码加载到内存中,并创建对应的 Class 对象,该对象包含了类的信息。
  2. 实例化对象: 通过 Class 对象,可以实例化类的对象。反射允许在运行时创建类的对象,而不需要在编译时知道类的确切类型。
  3. 动态获取信息: 通过 Class 对象,可以获取类的各种信息,包括类的名称、构造方法、字段、方法等。这使得程序在运行时能够根据需要动态地获取和操作类的信息。

总而言之,当一个类(.class文件)被classloader加载到内存后,它会将.class文件里面的内容加载到Metaspace中,并且会生成一个类对象。这个类对象存储在Metaspace中,它充当了访问类的结构和内容的入口,包括静态字段、方法等。
在这里插入图片描述
有兴趣的同学可以去学学JVM的相关知识。

二、反射有啥好处?

对于干干净净的小白同学,先绕道去第三部分了解一下反射的常用方法再来品味好吃的🌰,会更有感觉哦。
反射的好处咱们就举个有反射和没反射的例子对比说明一下子。
首先,定义一个支付接口 Mtwm

// Mtwm.java
public interface Mtwm {void payOnline();
}

然后,实现两个支付方式类,分别是 WeChatAliPay

// WeChat.java
public class WeChat implements Mtwm {@Overridepublic void payOnline() {System.out.println("我已经点了外卖,正在使用微信支付");}
}public class AliPay implements Mtwm {@Overridepublic void payOnline() {System.out.println("我已经点了外卖,正在使用支付宝支付");}
}

1. 没反射

接下来,创建一个测试类 Test,用于模拟前台选择支付方式:

// Test.java
public class Test {public static void main(String[] args) {String str = "微信";  // 模拟前台支付方式选择if ("微信".equals(str)) {pay(new WeChat());}if ("支付宝".equals(str)) {pay(new AliPay());}}public static void pay(Mtwm paymentMethod) {paymentMethod.payOnline();}
}

以上是使用多态的方式,已经不错了哦。但在实际应用中,若是我又增加了一个 “银行卡支付” 诸君又该如何应对 ? 我举手🙋,我回答。
无非就两步嘛:

1、创建一个新类,implement Mtwm,重写payOnline方法
2、在多加一个if的判断分支。

但是当我们引入反射机制,会发生什么神奇的事情呢?

2. 有反射

// Demo.java
import java.lang.reflect.Method;public class Demo {public static void main(String[] args) throws Exception {// 模拟前台支付方式选择String str = "com.zhaoss.test01.AliPay";  // 实际上是支付类的全限定路径// 利用反射Class<?> cls = Class.forName(str);Object instance = cls.newInstance();// 获取 payOnline 方法并调用Method method = cls.getMethod("payOnline");method.invoke(instance);}
}

各位有没有发现,通过使用反射,可以在不修改测试类的情况下引入新的支付方式。这样我们就只要创建一个新类(implement Mtwm,重写payOnline方法),然后提供新支付方式的实现类并传入其全路径名,而无需修改测试类。是不是很哇塞!!!

三、反射的常用方法

哥哥们,原谅我懒。我把输出写到注释里了,不好看的话可以直接搞到本地跑一下子。

1. 获取 Class 对象:

通过对象的 getClass() 方法或者类名的 .class 字面量可以获取类的 Class 对象。

public class Example {public static void main(String[] args) {// 通过对象的getClass()方法获取Class对象String str = "Hello, Reflect!";Class<?> classObj1 = str.getClass();System.out.println(classObj1.getName());  // 输出:java.lang.String// 通过类名的.class字面量获取Class对象Class<?> classObj2 = String.class;System.out.println(classObj2.getName());  // 输出:java.lang.String}
}

2. 获取类的构造方法:

通过 getConstructors() 方法获取类的所有公共构造方法,通过 getDeclaredConstructors() 获取所有构造方法(包括私有的)。

import java.lang.reflect.Constructor;public class Example {public Example(String message) {System.out.println("Constructor with message: " + message);}public static void main(String[] args) throws Exception {Class<?> clazz = Example.class;// 获取所有公共构造方法Constructor<?>[] constructors = clazz.getConstructors();for (Constructor<?> constructor : constructors) {System.out.println("Public Constructor: " + constructor);//输出:Public Constructor: public SystemStudy.Example(java.lang.String)}// 获取所有构造方法(包括私有的)Constructor<?>[] allConstructors = clazz.getDeclaredConstructors();for (Constructor<?> constructor : allConstructors) {System.out.println("All Constructor: " + constructor);//输出://All Constructor: public SystemStudy.Example(java.lang.String)//All Constructor: private SystemStudy.Example(java.lang.String,java.lang.Integer)}}
}

3. 获取类的字段信息:

通过 getFields() 方法获取类的所有公共字段,通过 getDeclaredFields() 获取所有字段(包括私有的)。

import java.lang.reflect.Field;public class Example {public int publicField;private String privateField;public static void main(String[] args) {Class<?> clazz = Example.class;// 获取所有公共字段Field[] fields = clazz.getFields();for (Field field : fields) {//输出:Public Field: public int SystemStudy.Example.publicFieldSystem.out.println("Public Field: " + field);}// 获取所有字段(包括私有的)Field[] allFields = clazz.getDeclaredFields();for (Field field : allFields) {//输出://All Field: public int SystemStudy.Example.publicField//All Field: private java.lang.String SystemStudy.Example.privateFieldSystem.out.println("All Field: " + field);}}
}

4. 获取类的方法信息:

通过 getMethods() 方法获取类的所有公共方法,通过 getDeclaredMethods() 获取所有方法(包括私有的)。
这里还有好多的Object包含的方法(wait、equals、hashCode等),太多了,我就写了两个关键的。

import java.lang.reflect.Field;
import java.lang.reflect.Method;public class Example {public void publicMethod() {System.out.println("Public Method");}private void privateMethod() {System.out.println("Private Method");}public static void main(String[] args) {Class<?> clazz = Example.class;// 获取所有公共方法Method[] methods = clazz.getMethods();for (Method method : methods) {//输出:Public Method: public void SystemStudy.Example.publicMethod()System.out.println("Public Method: " + method);}// 获取所有方法(包括私有的)Method[] allMethods = clazz.getDeclaredMethods();for (Method method : allMethods) {//输出//All Method: public void SystemStudy.Example.publicMethod()//All Method: private void SystemStudy.Example.privateMethod()System.out.println("All Method: " + method);}}
}

5. 创建对象和调用方法:

通过 newInstance() 方法创建类的实例,并通过 invoke() 方法调用类的方法。

import java.lang.reflect.Method;public class Example {public void sayHello(String name) {System.out.println("Hello, " + name + "!");}public static void main(String[] args) throws Exception {Class<?> clazz = Example.class;// 创建类的实例Object obj = clazz.newInstance();// 获取方法并调用Method method = clazz.getMethod("sayHello", String.class);method.invoke(obj, "Reflect");  // 输出:Hello, Reflect!}
}

这些是反射中常用的方法,通过这些方法,可以在运行时获取并操作类的信息,使得代码更加灵活和动态。还有很多方法啊,我就不挨个列举了。

四、总结

好啦,以上就是本次对于反射的讲解。安全到站,下车!!!对于我的驾驶技术苟同的兄弟姐妹们,点点赞👍。祝各位身体健康、吃嘛嘛香!!!

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

5214手持式千兆网络质量测试仪

5214手持式千兆网络质量测试仪 简述&#xff1a; 5214 手持式千兆网络质量测试仪是中电科思仪科技股份有限公司研发的综合性网络测 试仪器。此仪器具有网络故障的排查&#xff0c;网络设备的现场维护&#xff0c;网络性能的测试和分析&#xff0c;协议 仿真、解码、统计等功能…

目标检测 YOLOv5 - 推理时的数据增强

目标检测 YOLOv5 - 推理时的数据增强 flyfish 版本 YOLOv5 6.2 参考地址 https://github.com/ultralytics/yolov5/issues/303在训练时可以使用数据增强&#xff0c;在推理阶段也可以使用数据增强 在测试使用数据增强有个名字叫做Test-Time Augmentation (TTA) 实际使用中使…

Arduino驱动VL6180X光学测距传感器(OLED显示)

Arduino驱动VL6180X光学测距传感器&#xff08;OLED显示&#xff09; 简介原理模块参数接线图代码结果 简介 VL6108X三合一光电模块&#xff0c;芯片内集成了IR VSEL(vertical-cavity surface-emitting laser)红外垂直腔面发射激光器光源、接近传感器、环境光传感器&#xff0…

Java创建线程执行任务的方法(一)

目录 1.继承Thread类 2.实现Runnab类 2.1实现Runnable类 2.2使用Lambda表达式 3.实现Callable类 3.1返回Integer类型数据 3.2返回String类型数据 3.3返回Object类型数据 4.匿名内部类 创建线程的方法&#xff1a;继承Thread类&#xff1b;实现Runnab类&#xff1b;匿名…

Apipost一键压测参数化功能详解

最近更新中Apipost对UI页面进行了一些调整&#xff0c;另外一键压测功能支持参数化&#xff01;本篇文章将详细介绍这些改动&#xff01; API调试页面的细节改动 在请求区填入请求参数或脚本时会有相应的标识 如在Query中填入多个参数时上方会展示数量 在预、后执行脚本中写…

基于Java车间工时管理系统(源码+部署文档)

博主介绍&#xff1a; ✌至今服务客户已经1000、专注于Java技术领域、项目定制、技术答疑、开发工具、毕业项目实战 ✌ &#x1f345; 文末获取源码联系 &#x1f345; &#x1f447;&#x1f3fb; 精彩专栏 推荐订阅 &#x1f447;&#x1f3fb; 不然下次找不到 Java项目精品实…

海外社媒营销避坑指南:盘点最容易被人忽视的7大坑!

在全球数字化浪潮的推动下&#xff0c;海外社媒营销成为企业推广品牌、产品和服务的重要途径。然而&#xff0c;与其诱人的前景相对应的是众多的坑&#xff0c;需要企业精心规划和巧妙应对。本文Nox聚星将和大家盘一盘企业在海外社媒营销之路上最容易忽视的7个大坑&#xff0c;…

一面“短刀”出鞘,一面撤回IPO,蜂巢能源决定求稳

刚刚在12月12日的第四届电池日上全球首发蜂速超快充磷酸铁锂短刀电池&#xff0c;10天之后便主动撤回已经过上交所两次问询的IPO申请&#xff0c;终止了自己奔赴科创板的上市之旅。动力电池新贵蜂巢能源这套动作&#xff0c;让市场颇为遗憾——虽然当前国内资本市场环境确实不同…

AI赋能金融创新:技术驱动的未来金融革命

人工智能&#xff08;AI&#xff09;作为一种技术手段&#xff0c;正逐渐改变金融行业的方方面面。从风险管理到客户体验&#xff0c;从交易执行到反欺诈&#xff0c;AI带来了许多创新和机遇。本文将探讨AI在金融领域的应用和其赋能的金融创新。 金融领域一直以来都面临着复杂的…

计算机网络【DHCP动态主机配置协议】

DHCP 出现 电脑或手机需要 IP 地址才能上网。大刘有两台电脑和两台手机&#xff0c;小美有一台笔记本电脑、一台平板电脑和两台手机&#xff0c;老王、阿丽、敏敏也有几台终端设备。如果为每台设备手动配置 IP 地址&#xff0c;那会非常繁琐&#xff0c;一点儿也不方便。特别是…

潜力股的印度市场,为啥被风险投资人看空了?

KlipC报道&#xff1a;自2021年第四季度&#xff0c;印度超过英国&#xff0c;稳居世界第五大经济体之后&#xff0c;“印度市场”的潜力被不断提及。 KlipC的分析师Allen表示&#xff1a;“但对于风险投资行业来说&#xff0c;从2023年的数据看&#xff0c;似乎像是遭遇了一场…

鸿鹄电子招投标系统:源码级别解析电子招投标的精髓

招投标管理系统是一个集门户管理、立项管理、采购项目管理、采购公告管理、考核管理、报表管理、评审管理、企业管理、采购管理和系统管理于一体的综合性应用平台。它适用于招标代理、政府采购、企业采购和工程交易等业务的企业&#xff0c;旨在提高项目管理的效率和质量。该系…

SpireCV项目实战——电诈园区人员及房屋情况识别

项目介绍前言 随着科技的进步和大数据时代的到来&#xff0c;计算机视觉技术逐渐渗透到各个行业领域&#xff0c;为人们的生活和工作带来了诸多便利。近年来&#xff0c;电信诈骗案件频发&#xff0c;给社会带来了巨大的经济损失和心理负担。电诈园区作为电信诈骗的高发区域&a…

【PyQt5】QComboBox文字居中

你永远也无法预料到&#xff0c;Qt到底埋了多少坑(我的是PyQt5)&#xff0c; 一个破文本居中都要搞那么麻烦 一堆样式这里不生效那里不生效的真的是离谱 代码运行结果&#xff1a; import sys from PyQt5.QtWidgets import QApplication,QComboBox from PyQt5.QtWidgets impor…

Threejs 标签添加(单标签/多标签)

前言&#xff1a;网上写这个太少了&#xff0c;还写的乱&#xff0c;我就简单的整理下大家看下就会&#xff0c;有问题可以关注公众号: 技术链 1、创建工程vue 这个可以直接用命令创建 2、引入安装Threejs 依赖 3、编写标签引入依赖&#xff0c;可以使用 CSS2DRenderer,CSS3D…

堪比Postman!这款IDEA插件真好用!

Postman是大家最常用的API调试工具&#xff0c;那么有没有一种方法可以不用手动写入接口到Postman&#xff0c;即可进行接口调试操作&#xff1f;今天给大家推荐一款IDEA插件&#xff1a;Apipost Helper&#xff0c;写完代码就可以调试接口并一键生成接口文档&#xff01;而且还…

【计算机毕业设计】SSM游戏点评网站

项目介绍 本项目分为前后台&#xff0c;前台为普通用户登录&#xff0c;后台为管理员登录&#xff1b; 管理员角色包含以下功能&#xff1a; 管理员登录,管理员管理,网站用户管理,游戏资讯管理,游戏类型管理,城市信息管理,竞技场管理,游戏信息管理,游戏评价信息管理等功能。…

【Spark精讲】一文讲透SparkSQL物理执行计划

SparkSQL整体计划生成流程 大体分三步&#xff1a; (1)由 SparkSqlParser 中的 AstBuilder执行节点访问&#xff0c;将语法树的各种Context节点转换成对应的 LogicalPlan 节点&#xff0c;从而成为一棵未解析的逻辑算子树(Unresolved LogicalPlan)&#xff0c;此时的逻辑算子树…

基于CNN和双向gru的心跳分类系统

CNN and Bidirectional GRU-Based Heartbeat Sound Classification Architecture for Elderly People是发布在2023 MDPI Mathematics上的论文&#xff0c;提出了基于卷积神经网络和双向门控循环单元(CNN BiGRU)注意力的心跳声分类&#xff0c;论文不仅显示了模型还构建了完整的…

c语言-位操作符练习题

文章目录 前言一、n&(n-1)的运用场景(n为整数)二、&1 和 >>的应用场景总结 前言 本篇文章介绍利用c语言的位操作符解决一些练习题&#xff0c;目的是掌握各个位操作符的使用和应用场景。 表1.1为c语言中的位操作符 操作符含义&按位与|按位或^按位异或~按位…