Java学习——day22(Java反射基础入门)
文章目录
- 1.反射的定义
- 2. 认识反射的关键API
- 2.1 Class
- 2.2 Field
- 2.3 Method
- 2.4 Constructor
- 3. 示例代码讲解与分析
- 4. 编写反射示例代码的步骤
- 4.1 定义测试类
- 4.2 编写主程序,使用反射获取信息
- 4.3 通过反射创建对象并调用方法
- 5. 总结
- 6.今日生词
Java反射笔记
1.反射的定义
- 反射是什么?
Java反射是一种在运行时动态获取类的结构信息并操作对象的机制。通过反射,你可以:- 获取类信息:在程序运行时动态加载类,检查类的属性、方法和构造函数。
- 动态操作:可以动态调用对象的方法、修改对象的属性(即使是私有成员),甚至创建新的对象实例。
- 应用场景:
- 框架开发(如Spring、Hibernate)常常利用反射实现依赖注入、动态代理和数据绑定。
- 插件化开发:根据配置动态加载类,实现模块化扩展。
2. 认识反射的关键API
2.1 Class
- 作用:代表一个类或接口的运行时类型信息。
- 获取方式:
- 使用实例的
getClass()方法:Object obj = new Person(); Class<?> cls = obj.getClass(); - 使用静态方法
Class.forName("完整类名"):Class<?> cls = Class.forName("com.example.Person");
- 使用实例的
- 常用方法:
getName():获取类的全限定名。getDeclaredFields():获取所有声明的字段(包括私有字段)。getDeclaredMethods():获取所有声明的方法。getConstructors()和getDeclaredConstructors():获取公共构造函数或所有构造函数。
2.2 Field
- 作用:代表类的成员变量(字段)。
- 常用方法:
getName():返回字段名称。get(Object obj):获取指定对象上此字段的值。set(Object obj, Object value):修改指定对象上此字段的值。setAccessible(true):当字段是私有时,允许通过反射访问或修改其值。
- 注意事项:使用
setAccessible(true)时要注意安全性和封装性,最好在必要时才使用。
2.3 Method
- 作用:代表类中的方法。
- 常用方法:
getName():获取方法名称。invoke(Object obj, Object... args):在指定对象上调用此方法,传递必要的参数。getParameterTypes():获取方法参数类型数组。- 使用场景:动态调用对象方法,或在运行时根据方法名称决定调用哪个方法。
2.4 Constructor
- 作用:代表类的构造函数。
- 常用方法:
newInstance(Object... initargs):利用构造函数创建新实例,传入必要参数。getParameterTypes():获取构造函数的参数类型。
- 使用场景:动态创建对象实例,尤其是在编写通用工厂模式或插件式架构时非常有用。
3. 示例代码讲解与分析
下面是一段简单的示例代码,展示如何使用反射获取一个类的结构信息。假设我们有一个简单的 Person 类。
示例代码
// 定义一个简单的Person类
public class Person {private String name;private int age;// 构造函数public Person() {this.name = "Default";this.age = 0;}public Person(String name, int age) {this.name = name;this.age = age;}// 方法:打印信息public void sayHello() {System.out.println("Hello, my name is " + name);}
}
反射获取类信息的示例
import java.lang.reflect.*;public class ReflectionDemo {public static void main(String[] args) {try {// 1. 获取Person类的Class对象Class<?> personClass = Class.forName("Person");// 2. 获取类的名称System.out.println("类名称:" + personClass.getName());// 3. 获取所有构造函数Constructor<?>[] constructors = personClass.getDeclaredConstructors();System.out.println("构造函数:");for (Constructor<?> constructor : constructors) {System.out.println(" " + constructor);}// 4. 获取所有字段(包括私有字段)Field[] fields = personClass.getDeclaredFields();System.out.println("字段:");for (Field field : fields) {System.out.println(" " + field.getName());}// 5. 获取所有方法Method[] methods = personClass.getDeclaredMethods();System.out.println("方法:");for (Method method : methods) {System.out.println(" " + method.getName());}} catch (ClassNotFoundException e) {e.printStackTrace();}}
}
分析
- Class.forName(“Person”):动态加载
Person类,通过其完全限定名获得Class对象。 - 获取构造函数:调用
getDeclaredConstructors()返回该类所有构造函数,并输出构造函数的签名。 - 获取字段:调用
getDeclaredFields(),即使字段为私有也能获取到。通过field.getName()输出每个字段的名称。 - 获取方法:调用
getDeclaredMethods()得到类中所有声明的方法,输出方法名称以便了解类提供了哪些操作。
4. 编写反射示例代码的步骤
4.1 定义测试类
创建一个名为 Person 的类,包含如下内容:
- 字段:
name(String)、age(int)。 - 构造函数:无参构造函数和带参构造函数。
- 方法:例如
sayHello()用于输出欢迎信息。
4.2 编写主程序,使用反射获取信息
1.加载类:使用 Class.forName("Person") 获取 Class 对象。
2.获取构造函数:使用 getDeclaredConstructors() 获取所有构造函数。
3.获取字段:使用 getDeclaredFields() 获取所有字段,必要时调用 setAccessible(true) 访问私有字段。
4.获取方法:使用getDeclaredMethods()获取所有方法。
4.3 通过反射创建对象并调用方法
- 实例化对象:使用获取到的构造函数(如带参构造函数)调用 newInstance() 创建 Person 对象。
- 修改字段:如果需要,可以通过反射修改私有字段的值。例如,调用 field.setAccessible(true) 后,再使用
field.set(personInstance, "新的名字")。 - 调用方法:使用
Method.invoke(object, args...)来调用sayHello()方法,并观察控制台输出。
示例代码扩展:创建对象并调用方法
import java.lang.reflect.*;public class ReflectionDemoExtended {public static void main(String[] args) {try {// 1. 加载Person类的Class对象Class<?> personClass = Class.forName("Person");// 2. 获取带参构造函数,并创建对象Constructor<?> constructor = personClass.getConstructor(String.class, int.class);Object personInstance = constructor.newInstance("Alice", 25);// 3. 修改私有字段(假设需要修改name)Field nameField = personClass.getDeclaredField("name");nameField.setAccessible(true); // 允许访问私有字段nameField.set(personInstance, "Bob");// 4. 调用sayHello方法Method sayHelloMethod = personClass.getDeclaredMethod("sayHello");sayHelloMethod.invoke(personInstance);} catch (Exception e) {e.printStackTrace();}}
}
代码说明
- 创建对象:通过
getConstructor(String.class, int.class) ``获取带参构造函数,然后调用newInstance(“Alice”, 25) `创建对象。 - 修改字段:通过
getDeclaredField("name")获取name字段,设置为可访问后,用set()方法修改对象的name值为 “Bob”。 - 调用方法:获取
sayHello方法,并调用invoke()执行该方法,观察输出验证修改后的值。
5. 总结
- 反射的优势:可以在运行时动态操作对象和类,灵活应对各种需求(如插件化、依赖注入)。
- 需要注意的点:
- 反射操作可能破坏封装性,使用时需要谨慎。
- 反射会有一定的性能损耗,不建议在性能敏感的场景中大量使用。
6.今日生词
1.tongue 2.circunstance 3.tension 4.economist 5.accommodate
相关文章:
Java学习——day22(Java反射基础入门)
文章目录 1.反射的定义2. 认识反射的关键API2.1 Class2.2 Field2.3 Method2.4 Constructor 3. 示例代码讲解与分析4. 编写反射示例代码的步骤4.1 定义测试类4.2 编写主程序,使用反射获取信息4.3 通过反射创建对象并调用方法 5. 总结6.今日生词 Java反射笔记 1.反射的…...
BN 层做预测的时候, 方差均值怎么算
✅ 一、Batch Normalization(BN)回顾 BN 层在训练和推理阶段的行为是不一样的,核心区别就在于: 训练时用 mini-batch 里的均值方差,预测时用全局的“滑动平均”均值方差。 🧪 二、训练阶段(Trai…...
JS 其他事件类型
页面加载 事件 window.addEvent() window.addEventListener(load,function(){const btn document.querySelector(button)btn.addEventListener(click,function(){alert(按钮)})})也可以给其他标签加该事件 HTML加载事件 找html标签 也可以给页面直接赋值...
AI Agent设计模式五:Orchestrator
概念 :中央任务调度中枢 ✅ 优点:全局资源协调,确保任务执行顺序❌ 缺点:单点故障风险,可能成为性能瓶颈 import operator import osfrom langchain.schema import SystemMessage, HumanMessage from langchain_opena…...
在Hive中,将数据从一个表查询并插入到另一个表
1. 确认目标表结构 确保目标表已存在且结构与查询结果匹配。若不存在,需先创建: CREATE TABLE target_table ( id INT, name STRING ) PARTITIONED BY (dt STRING) STORED AS ORC; 2. 选择插入方式 覆盖插入(替换现有数据࿰…...
Android Fresco 框架缓存模块源码深度剖析(二)
Android Fresco 框架缓存模块源码深度剖析 一、引言 本人掘金号,欢迎点击关注:https://juejin.cn/user/4406498335701950 在 Android 应用开发中,图片加载和处理是常见且重要的功能。频繁的图片加载不仅会消耗大量的网络流量,还…...
MySQL基础 [三] - 数据类型
目录 数据类型分类 编辑 数值类型 tinyint bit 浮点类型 float decimal 字符串类型 char varchar varchar和char的比较和选择 日期和时间类型 enum和set enum类型 set类型 enum和set的类型查找 数据类型分类 数值类型 tinyint TINYINT[(M)] [UNSIGNED]是 …...
不用训练,集成多个大模型产生更优秀的输出
论文标题 Collab: Controlled Decoding using Mixture of Agents for LLM Alignment 论文地址 https://arxiv.org/pdf/2503.21720 作者背景 JP摩根,马里兰大学帕克分校,普林斯顿大学 动机 大模型对齐(alignment)的主要目的…...
随笔1 认识编译命令
1.认识编译命令 1.1 解释gcc编译命令: gcc test1.cpp -o test1 pkg-config --cflags --libs opencv 命令解析: gcc:GNU C/C 编译器,用于编译C/C代码。 test1.cpp:源代码文件。 -o test1:指定输出的可执行文件名为t…...
【数据结构】并查集应用
修改数组 题目:检查ai是否出现过,出现过就不断1,使成为第一个没有出现过的。这样得到一个不重复数组。 祖先是该数字能使用的最小数字,当使用完后,祖先把这个格子占了,下次再来,就得使用后一个…...
python基础-16-处理csv文件和json数据
文章目录 【README】【16】处理csv文件和json数据【16.1】csv模块【16.1.1】reader对象【16.1.2】在for循环中, 从reader对象读取数据【16.1.3】writer对象【16.1.5】DictReader与DictWriter对象 【16.4】json模块【16.4.1】使用loads()函数读取json字符串并转为jso…...
MySQL Explain 分析 SQL 执行计划
MySQL Explain 分析 SQL 执行计划 在优化 SQL 查询性能时,了解查询的执行计划至关重要。MySQL 提供的 EXPLAIN 工具能够帮助我们深入了解查询语句的执行过程、索引使用情况以及潜在的性能瓶颈。本文将详细介绍如何使用 EXPLAIN 分析 SQL 执行计划,并探讨…...
Hyperlane 框架路由功能详解:静态与动态路由全掌握
Hyperlane 框架路由功能详解:静态与动态路由全掌握 Hyperlane 框架提供了强大而灵活的路由功能,支持静态路由和动态路由两种模式,让开发者能够轻松构建各种复杂的 Web 应用。本文将详细介绍这两种路由的使用方法。 静态路由:简单…...
理解进程和线程的概念
在操作系统中,进程和线程都是执行的基本单位,但它们在性质和管理方面有所不同 进程 定义: 进程是一个正在运行的程序的实例,是操作系统资源分配的基本单位。特点: 独立性:每个进程有其独立的内存空间、数据栈和其他辅助数据。重…...
铰链损失函数 Hinge Loss和Keras 实现
一、说明 在为了了解 Keras 深度学习框架的来龙去脉,本文介绍铰链损失函数,然后使用 Keras 实现它们以进行练习并了解它们的行为方式。在这篇博客中,您将首先找到两个损失函数的简要介绍,以确保您在我们继续实现它们之前直观地理解…...
瑞数信息发布《BOTS自动化威胁报告》,揭示AI时代网络安全新挑战
近日,瑞数信息正式发布《BOTS自动化威胁报告》,力求通过全景式观察和安全威胁的深度分析,为企业在AI时代下抵御自动化攻击提供安全防护策略,从而降低网络安全事件带来的影响,进一步增强业务韧性和可持续性。 威胁一&am…...
树莓派llama.cpp部署DeepSeek-R1-Distill-Qwen-1.5B
树莓派的性能太低了,我们需要对模型进行量化才能使用,所以现在的方案是,在windows上将模型格式和量化处理好,然后再将模型文件传输到树莓派上。而完成上面的操作就需要部署llama.cpp。 三、环境的准备 这里要求大家准备…...
小菜Go:Ubuntu下Go语言开发环境搭建
前置要求Ubuntu环境搭建 文章推荐 此处推荐一个比较好的文章,基本按部就班就欧克~ 安装虚拟机(VMware)保姆级教程(附安装包)_vmware虚拟机-CSDN博客 安装可能遇到的问题 虚拟机安装遇到的问题如:Exception…...
FLV格式:流媒体视频的经典选择
FLV格式:流媒体视频的经典选择 FLV(Flash Video)格式曾经是流媒体视频的主力军,在互联网视频的早期时代广泛应用于视频网站和多媒体平台。凭借其高效的压缩和较小的文件体积,FLV成为了许多视频内容创作者和平台的首选…...
需求分析-用例图绘制、流程图绘制
第一,引论 需求分析是开发的第一步,也是我个人认为最重要的一步。 技术难题的克服,甚至在我心里,还要排在需求分析后面。 如果需求分析做好了,数据库就更容易建立,数据库建好了,业务逻辑写起…...
Windows安装 PHP 8 和mysql9,win下使用phpcustom安装php8.4.5和mysql9
百度搜索官网并下载phpcustom,然后启动环境,点击网站管理 里面就有php8最新版,可以点mysql设置切mysql9最新版,如果你用最新版无法使用,说明你的php程序不支持最新版的mysql MySQL 9.0 引入了一些新的 SQL 模式和语法变…...
http://noi.openjudge.cn/_2.5基本算法之搜索_1804:小游戏
文章目录 题目深搜代码宽搜代码深搜数据演示图总结 题目 1804:小游戏 总时间限制: 1000ms 内存限制: 65536kB 描述 一天早上,你起床的时候想:“我编程序这么牛,为什么不能靠这个赚点小钱呢?”因此你决定编写一个小游戏。 游戏在一…...
手写JSX实现虚拟DOM
🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》、《前端求职突破计划》 🍚 蓝桥云课签约作者、…...
Spring Boot 中的 Bean
2025/4/6 向全栈工程师迈进! 一、Bean的扫描 在之前,对于Bean的扫描,我们可以在XML文件中书写标签,来指定要扫描的包路径,如下所示,可以实通过如下标签的方式: <context:component-scan base-package&…...
C++17更新内容汇总
C17 是 C14 的进一步改进版本,它引入了许多增强特性,优化了语法,并提升了编译期计算能力。以下是 C17 的主要更新内容: 1. 结构化绑定(Structured Bindings) 允许同时解构多个变量,从 std::tup…...
ST 芯片架构全景速览:MCU、无线 SoC、BLE 模块、MPU 差异详解
在嵌入式开发中,ST 是一个非常常见的芯片厂商,其产品线覆盖了 MCU、无线芯片、BLE 模块以及运行 Linux 的 MPU 等多个领域。很多开发者初次接触 ST 时会对这些产品之间的关系感到困惑。 本文从分类视角出发,带你快速了解 ST 芯片家族的核心架构和主要用途。 🧭 ST 芯片四…...
AtCoder Beginner Contest 400(ABCDE)
A - ABC400 Party 翻译: 在 ABC400 的纪念仪式上,我们想把 400 人排成 A 行 B 列的长方形,且不留任何空隙。 给你一个正整数 A,请打印可以这样排列的正整数 B 的值。如果没有这样的正整数 B,则打印-1。 思路ÿ…...
Flask+Vue构建图书管理系统及Echarts组件的使用
教程视频链接从零开始FlaskVue前后端分离图书管理系统 后端 项目下载地址 其中venv为该项目的虚拟环境,已安装所有依赖 使用方法: 在pycharm终端中flask create一下(因为写了一个自定义命令的代码),初始化books数据…...
【项目管理】第2章 信息技术发展 --知识点整理
Oracle相关文档,希望互相学习,共同进步 风123456789~-CSDN博客 (一)知识总览 对应:第1章-第5章 (二)知识笔记 二、信息技术的发展 1. 信息技术及其发展 1)计算机软硬件 计算机硬件由电子机械、光电元件等组成的物理装置,提供物质基础给计算机软件运行。软件包括程…...
Spring 中有哪些设计模式?
🧠 一、Spring 中常见的设计模式 设计模式类型Spring 中的应用场景单例模式创建型默认 Bean 是单例的工厂模式创建型BeanFactory、FactoryBean抽象工厂模式创建型ApplicationContext 提供多个工厂接口代理模式结构型AOP 动态代理(JDK/CGLIB)…...
