JAVA基础 - 反射
目录
一. 简介
二. java.lang.Class类
三. java.lang.reflect包
四. 创建对象
五. 调用方法
六. 调用成员变量
一. 简介
反射是 Java 语言中的一种强大机制,允许程序在运行时动态地获取类的信息、访问类的成员(包括字段、方法和构造函数)以及操作这些成员。
通过反射,您可以:
在运行时获取类的名称、父类、实现的接口等信息。
访问和修改对象的私有字段的值。
调用对象的私有方法。
在运行时创建类的实例。
反射的主要类和接口包括:
Class
类:表示一个类或接口在 Java 运行时的对象。
Field
类:表示类的字段。
Method
类:表示类的方法。
Constructor
类:表示类的构造函数。
二. java.lang.Class类
java.lang.Class
类在 Java 反射机制中起着核心作用。
它用于表示正在运行的 Java 应用程序中的类和接口。通过这个类,可以获取关于类的各种信息,如类的名称、属性、方法、父类、实现的接口等。
以下是 Class
类的一些常见方法和用途:
forName(String className)
:根据类的全限定名加载并返回对应的Class
对象。
getSimpleName()
:获取类的简单名称(不包含包名)。
getCanonicalName()
:获取类的规范名称(包含包名)。
getSuperclass()
:获取父类的Class
对象。
getInterfaces()
:获取实现的接口的Class
对象数组。
getDeclaredFields()
:获取本类声明的所有字段(包括私有字段)。
getFields()
:获取本类及父类的所有公有字段。
getDeclaredMethods()
:获取本类声明的所有方法(包括私有方法)。
getMethods()
:获取本类及父类的所有公有方法。
newInstance()
:创建类的新实例(调用无参构造函数)。
public class ClassExample {public static void main(String[] args) {try {Class<?> clazz = Class.forName("java.util.ArrayList");System.out.println("类的简单名称: " + clazz.getSimpleName());System.out.println("类的规范名称: " + clazz.getCanonicalName());Class<?> superclass = clazz.getSuperclass();System.out.println("父类: " + superclass.getCanonicalName());} catch (ClassNotFoundException e) {e.printStackTrace();}}
}
总之,Class
类为 Java 程序在运行时动态获取和操作类的信息提供了强大的支持。
三. java.lang.reflect包
java.lang.reflect
包提供了用于反射操作的类和接口,允许在运行时检查和操作类、方法、字段和构造函数等。
以下是该包中的一些重要类和接口:
Field
类:表示类的字段。可以通过它获取和设置字段的值,无论字段是公有、私有还是受保护的。
Method
类:代表类的方法。可以获取方法的名称、参数类型、返回类型,并能够在运行时调用方法。
Constructor
类:表示类的构造函数。可用于获取构造函数的参数类型,并通过它创建类的实例。
Array
类:提供了一些静态方法来操作数组。
使用反射机制虽然强大,但也存在一些潜在的问题。例如,反射可能会破坏封装性,导致代码更难以理解和维护。此外,由于反射需要在运行时进行类型检查和方法调用,可能会带来一定的性能开销。
以下是一个简单的示例,展示如何使用 java.lang.reflect
包中的类获取类的方法信息:
import java.lang.reflect.Method;public class ReflectPackageExample {public static void main(String[] args) {try {Class<?> clazz = Class.forName("YourClassName");Method[] methods = clazz.getDeclaredMethods();for (Method method : methods) {System.out.println("方法名: " + method.getName());Class<?>[] parameterTypes = method.getParameterTypes();System.out.print("参数类型: ");for (Class<?> parameterType : parameterTypes) {System.out.print(parameterType.getName() + " ");}System.out.println();}} catch (ClassNotFoundException e) {e.printStackTrace();}}
}
总之,java.lang.reflect
包为 Java 提供了在运行时进行动态类型探索和操作的能力,但应谨慎使用,权衡其带来的灵活性和可能产生的问题。
四. 创建对象
在 Java 中使用反射来创建对象,主要通过以下步骤:
获取要创建对象的类的
Class
对象。可以通过Class.forName("全限定类名")
或者 对象的getClass()
方法来获取。获取类的构造函数。使用
getDeclaredConstructor(参数类型列表)
或getConstructor(参数类型列表)
方法。通过构造函数创建对象。使用
newInstance(参数值列表)
方法。
以下是一个示例代码:
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;public class ReflectionObjectCreation {public static void main(String[] args) {try {// 加载类Class<?> clazz = Class.forName("YourClassName");// 获取无参构造函数Constructor<?> constructor = clazz.getConstructor();// 使用无参构造函数创建对象Object object = constructor.newInstance();// 或者获取有参构造函数,并创建对象Constructor<?> parameterizedConstructor = clazz.getConstructor(String.class);Object parameterizedObject = parameterizedConstructor.newInstance("Parameter Value");} catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) {e.printStackTrace();}}
}
需要注意的是,使用反射创建对象可能会导致一些性能开销,并且在实际开发中应谨慎使用,通常用于一些特殊的场景,如依赖注入框架、对象工厂等。
五. 调用方法
在 Java 中使用反射来调用方法,通常按照以下步骤进行:
- 获取要操作的类的
Class
对象。- 根据方法名和参数类型获取对应的
Method
对象。- 创建类的实例。
- 使用
Method
对象的invoke
方法来调用方法,并传递实例对象和参数值。
以下是一个示例代码:
import java.lang.reflect.Method;public class ReflectionMethodInvocation {public static void main(String[] args) {try {// 加载类Class<?> clazz = Class.forName("YourClassName");// 获取指定方法Method method = clazz.getMethod("methodName", parameterTypes);// 创建对象实例Object instance = clazz.newInstance();// 调用方法method.invoke(instance, parameterValues);} catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {e.printStackTrace();}}
}
在上述代码中,您需要将 "YourClassName"
替换为实际的类名,"methodName"
替换为要调用的方法名,parameterTypes
替换为方法参数的类型数组,parameterValues
替换为实际传递的参数值。
使用反射调用方法时要处理可能抛出的各种异常,并且要注意性能和安全性方面的考虑。一般情况下,只有在必要时才使用反射来调用方法,例如在框架或特定的动态场景中。
六. 调用成员变量
在 Java 中使用反射来访问和操作成员变量,可以按照以下步骤进行:
获取要操作的类的
Class
对象。根据成员变量名获取对应的
Field
对象。如果成员变量是私有访问权限,需要设置可访问性。
对成员变量进行读写操作。
以下是一个示例代码:
import java.lang.reflect.Field;public class ReflectionFieldAccess {public static void main(String[] args) {try {// 加载类Class<?> clazz = Class.forName("YourClassName");// 获取指定成员变量Field field = clazz.getDeclaredField("fieldName");// 如果是私有变量,设置可访问性field.setAccessible(true);// 创建对象实例Object instance = clazz.newInstance();// 读取成员变量的值Object value = field.get(instance);System.out.println("Value of the field: " + value);// 设置成员变量的值field.set(instance, newValue);} catch (ClassNotFoundException | NoSuchFieldException | InstantiationException | IllegalAccessException e) {e.printStackTrace();}}
}
在上述代码中,将 "YourClassName"
替换为实际的类名,"fieldName"
替换为要操作的成员变量名,newValue
替换为要设置的新值。
使用反射访问私有成员变量时,需要设置可访问性,否则会抛出异常。同时,反射操作可能会影响代码的封装性和安全性,应谨慎使用。
相关文章:

JAVA基础 - 反射
目录 一. 简介 二. java.lang.Class类 三. java.lang.reflect包 四. 创建对象 五. 调用方法 六. 调用成员变量 一. 简介 反射是 Java 语言中的一种强大机制,允许程序在运行时动态地获取类的信息、访问类的成员(包括字段、方法和构造函数ÿ…...
【系统架构设计师】二十二、嵌入式系统架构设计理论与实践③
目录 一、鸿蒙操作系统架构案例分析 1.1 鸿蒙操作系统定义 1.2 鸿蒙的层次化分析 1.2.1 内核层 1.2.2 系统服务层 1.2.3 框架层 1.2.4 应用层 1.3 鸿蒙操作系统的架构分析 1.3.1 鸿蒙操作系统架构具有4个技术特性 1.3.2 分布式架构所带来的优势 1.3.3 HarmonyOS 架构…...

【轨物推荐】经济长波:创新周期的历史
原创 丑丑姐姐 专利分析可视化 2021年08月01日 21:18 图片来源:Visual Capitalist 在开始本文之前,我们先来学习两个概念: 经济长波(Long Waves),亦称“大循环理论”、“康德拉季耶夫周期”。经济长波理论…...

springboot高校勤工俭学平台-计算机毕业设计源码66824
摘 要 本研究基于Spring Boot企业框架,设计并实现了一款高校勤工俭学平台,包括首页、通知公告、新闻通知和岗位信息等功能模块。该平台旨在为高校学生提供便捷的勤工俭学信息发布与查询服务,促进校园内部劳动力资源的充分利用和高效管理。在研…...

CRM是什么?如何用CRM管理好客户?
在企业的销售运营中,客户是是贯穿始终的主体。客户的需求、偏好与满意度,指引着企业未来改变、优化的方向。而企业销售运营的核心,就是“客户至上”。 面对庞杂的客户信息,如何快速高效的进行客户管理呢?那就是要有一…...

编程入门:大学新生的指南与策略
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

Spring Cloud中怎么使用Resilience4j Retry对OpenFeign进行重试
在微服务架构中,服务之间的通信是非常频繁的。而使用OpenFeign可以极大简化微服务之间的HTTP通信。但在复杂的分布式系统中,服务之间的调用可能会因为网络问题、服务故障等原因而失败。因此,实现服务调用的重试机制显得尤为重要。Resilience4…...

【Redis 进阶】事务
Redis 的事务和 MySQL 的事务概念上是类似的,都是把一系列操作绑定成一组,让这一组能够批量执行。 一、Redis 的事务和 MySQL 事务的区别 1、MySQL 事务 原子性:把多个操作打包成一个整体。(要么全都做,要么都不做&am…...

Linux的防火墙
一、防火墙概述 防火墙是一种计算机硬件和软件的结合,使internet和intranet之间建立一个安全网关(Security Gateway),从而保护内网免受非法用户侵入的技术。 防火墙主要由服务访问规则、验证工具、包过滤和应用网关4个部分组成。…...

跟张良均老师学大数据人工智能-批量集训营开班中
随着我国大数据和人工智能产业的飞速发展,未来社会对高素质科技人才的需求日益旺盛。为助力广大青少年提前掌握前沿技术,实现自我价值,泰迪智能科技多名优秀老师联合打造暑期大数据人工智能集训营,旨在培养具备创新精神和实战能力…...

2024年音频剪辑必备:五大最佳音频编辑软件精选!
在数字时代,音频剪辑已成为创意表达的重要工具。无论是音乐制作、播客编辑还是视频后期,一款优秀的音频剪辑软件都是不可或缺的。推荐五款备受推崇的音频剪辑工具。 福昕音频剪辑 链接:https://www.foxitsoftware.cn/audio-clip/ 福昕音频…...
Native Programs(本机程序)
Native Programs System Program(系统程序)Config ProgramStake ProgramVote ProgramAddress Lookup Table ProgramBPF LoaderEd25519 ProgramSecp256k1 Program Solana contains a small handful of native programs that are part of the validator im…...
RisingWave 1.10 发布!新增用户自定义聚合函数
我们非常高兴地宣布:RisingWave 1.10 版本正式发布!新版本为大家带来了许多重要更新,例如:新增用户自定义聚合函数 (UDAF)、支持从游标获取多个更新、支持可溢出哈希 Join、增强 CDC 连接器、新增 Sink 连接器等。一起来了解本次更…...

Modbus通讯协议
Modbus通讯协议 Modbus协议是一种用于电子控制器之间的通信协议,它允许不同类型的设备之间进行通信,以便进行数据交换和控制。Modbus协议最初为可编程逻辑控制器(PLC)通信开发,现已广泛应用于工业自动化领…...

fal.ai发布超分辨率模型——AuraSR V2
今天,我们发布了单步 GAN 升频器的第二个版本: AuraSR。 我们在上个月发布了 AuraSR v1,社区的反响让我们深受鼓舞,因此我们立即开始了新版本的训练。 AuraSR 基于 Adobe Gigagan 论文,以 lucidrain 的实现为起点。Gi…...

SYD88xx代码复位不成功和解决办法
原来的复位代码如下: void ota_manage(void){#ifdef _OTA_if(ota_state){switch(ota_state){case 1 : #if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)dbg_printf("start FwErase\r\n");#endifCmdFwErase();#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)db…...
加油,为Vue3提供一个可媲美Angular的ioc容器
为什么要为Vue3提供ioc容器 Vue3因其出色的响应式系统,以及便利的功能特性,完全胜任大型业务系统的开发。但是,我们不仅要能做到,而且要做得更好。大型业务系统的关键就是解耦合,从而减缓shi山代码的生长。而ioc容器是…...
RS485 CAN SPI IIC UART RS232这些通信协议传输距离、传输速度对比给出比较顺序-笔记(面试必备)
各类通信协议(RS485、CAN、SPI、I2C、UART、RS232)的传输距离和传输速度各有不同,适用于不同的应用场景。以下是这些通信协议的传输距离和传输速度的对比及排序: 传输距离比较(从长到短) RS485 最大传输距…...

高频JMeter软件测试面试题
近期,有很多粉丝在催更关于Jmeter的面试题,索性抽空整理了一波,以下是一些高频JMeter面试题,拿走不谢~ 一、JMeter的工作原理 JMeter就像一群将请求发送到目标服务器的用户一样,它收集来自目标服务器的响应以及其他统计…...

iptables netfilter
iptables -L --line...

铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...

微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...

使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统
💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「storms…...