Java 反射机制学习
Java 反射机制详解
Java 反射(Reflection)是 Java 语言的一种强大特性,允许程序在运行时动态地获取类的信息并操作类或对象的属性、方法和构造器。反射机制打破了 Java 的封装性,但也提供了极大的灵活性,常用于框架开发、动态代理、注解处理等场景。
目录
- 反射的基本概念
- 反射的核心类
- 获取 Class 对象
- 获取类的信息
- 操作类的属性
- 调用类的方法
- 操作构造器
- 反射的应用场景
- 反射的优缺点
- 代码示例
反射的基本概念
反射是指在程序运行时,能够动态地获取类的信息(如类名、方法、属性等),并能够操作这些信息。通过反射,可以在运行时创建对象、调用方法、访问属性,而不需要在编译时知道类的具体信息。
反射的核心类
Java 反射的核心类位于 java.lang.reflect 包中,主要包括:
- Class:表示类的类型信息。
- Field:表示类的属性。
- Method:表示类的方法。
- Constructor:表示类的构造器。
获取 Class 对象
要使用反射,首先需要获取类的 Class 对象。以下是获取 Class 对象的三种方式:
1. 通过 Class.forName()
Class<?> clazz = Class.forName("java.lang.String");
2. 通过 .class 语法
Class<?> clazz = String.class;
3. 通过对象的 getClass() 方法
String str = "Hello";
Class<?> clazz = str.getClass();
获取类的信息
通过 Class 对象,可以获取类的名称、修饰符、父类、接口等信息。
示例代码
Class<?> clazz = String.class;// 获取类名
System.out.println("类名: " + clazz.getName());// 获取简单类名
System.out.println("简单类名: " + clazz.getSimpleName());// 获取修饰符
int modifiers = clazz.getModifiers();
System.out.println("修饰符: " + Modifier.toString(modifiers));// 获取父类
Class<?> superClass = clazz.getSuperclass();
System.out.println("父类: " + superClass.getName());// 获取实现的接口
Class<?>[] interfaces = clazz.getInterfaces();
for (Class<?> iface : interfaces) {System.out.println("接口: " + iface.getName());
}
操作类的属性
通过反射可以获取和修改类的属性(包括私有属性)。
示例代码
class Person {private String name;public int age;public Person(String name, int age) {this.name = name;this.age = age;}
}public class ReflectionExample {public static void main(String[] args) throws Exception {Person person = new Person("Alice", 25);Class<?> clazz = person.getClass();// 获取公有属性Field ageField = clazz.getField("age");System.out.println("age: " + ageField.get(person));// 获取私有属性Field nameField = clazz.getDeclaredField("name");nameField.setAccessible(true); // 设置可访问System.out.println("name: " + nameField.get(person));// 修改属性值nameField.set(person, "Bob");System.out.println("修改后的 name: " + nameField.get(person));}
}
调用类的方法
通过反射可以调用类的方法(包括私有方法)。
示例代码
class Calculator {public int add(int a, int b) {return a + b;}private int multiply(int a, int b) {return a * b;}
}public class ReflectionExample {public static void main(String[] args) throws Exception {Calculator calculator = new Calculator();Class<?> clazz = calculator.getClass();// 调用公有方法Method addMethod = clazz.getMethod("add", int.class, int.class);int result = (int) addMethod.invoke(calculator, 2, 3);System.out.println("add 结果: " + result);// 调用私有方法Method multiplyMethod = clazz.getDeclaredMethod("multiply", int.class, int.class);multiplyMethod.setAccessible(true); // 设置可访问int product = (int) multiplyMethod.invoke(calculator, 2, 3);System.out.println("multiply 结果: " + product);}
}
操作构造器
通过反射可以创建类的实例。
示例代码
class Person {private String name;private int age;public Person() {}public Person(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Person{name='" + name + "', age=" + age + "}";}
}public class ReflectionExample {public static void main(String[] args) throws Exception {Class<?> clazz = Person.class;// 获取无参构造器Constructor<?> constructor1 = clazz.getConstructor();Person person1 = (Person) constructor1.newInstance();System.out.println("无参构造器创建的对象: " + person1);// 获取带参构造器Constructor<?> constructor2 = clazz.getConstructor(String.class, int.class);Person person2 = (Person) constructor2.newInstance("Alice", 25);System.out.println("带参构造器创建的对象: " + person2);}
}
反射的应用场景
- 框架开发:如 Spring 框架通过反射实现依赖注入。
- 动态代理:如 JDK 动态代理通过反射调用目标方法。
- 注解处理:通过反射读取注解信息。
- 工具类:如 Apache Commons BeanUtils 使用反射操作 JavaBean。
反射的优缺点
优点
- 灵活性:可以在运行时动态操作类和对象。
- 通用性:适用于编写通用框架和工具。
缺点
- 性能开销:反射操作比直接调用慢。
- 安全性问题:可以访问私有成员,破坏封装性。
- 代码可读性差:反射代码通常难以理解和维护。
代码示例
以下是一个完整的反射示例,展示了如何获取类信息、操作属性和方法、调用构造器:
import java.lang.reflect.*;class Student {private String name;public int age;public Student() {}public Student(String name, int age) {this.name = name;this.age = age;}public void display() {System.out.println("Name: " + name + ", Age: " + age);}private void secretMethod() {System.out.println("这是一个私有方法");}
}public class ReflectionExample {public static void main(String[] args) throws Exception {// 获取 Class 对象Class<?> clazz = Class.forName("Student");// 创建对象Constructor<?> constructor = clazz.getConstructor(String.class, int.class);Object student = constructor.newInstance("Alice", 20);// 获取并修改属性Field nameField = clazz.getDeclaredField("name");nameField.setAccessible(true);nameField.set(student, "Bob");Field ageField = clazz.getField("age");ageField.set(student, 22);// 调用方法Method displayMethod = clazz.getMethod("display");displayMethod.invoke(student);Method secretMethod = clazz.getDeclaredMethod("secretMethod");secretMethod.setAccessible(true);secretMethod.invoke(student);}
}
通过本文,你应该对 Java 反射有了全面的了解。反射是一个强大的工具,但需要谨慎使用,避免滥用导致性能问题和代码可读性下降。
相关文章:
Java 反射机制学习
Java 反射机制详解 Java 反射(Reflection)是 Java 语言的一种强大特性,允许程序在运行时动态地获取类的信息并操作类或对象的属性、方法和构造器。反射机制打破了 Java 的封装性,但也提供了极大的灵活性,常用于框架开…...
GetCurrentTime
在实际编程中难免要获取当前时间并且进行格式化,本文给出了多种 GetCurrentTime() 方法以供选择。 C语言下使用strftime C 语言中可以使用 <time.h> 中的函数来获取和格式化时间 #include <stdio.h> #include <time.h>char* getCurrentTime() …...
计算机的结构形式
微机的机构形式 台式个人微机 最开始的微机(计算机)都是台式的,到目前为止仍是个人微机的主要形式。台式机按照电脑机箱的放置形式,分为卧式和立式两种。台式机需要放在桌面上或者留有专门放置机箱位置,他的主机、键…...
SSL/TLS 1.2过程:Client端如何验证服务端证书?
快速回顾非对称加密和对称加密 首先快速说一下非对称加密和对称加密。非对称加密,就是有一个公钥和私钥(成对存在)。 公钥对一段文本A加密得到文本B,只有对应的私钥能对B解密得到A。 私钥对一段文本C加密得到文本D,只有对应的公钥能对D解密得…...
Python(学习一)
做网站有成熟的框架像FLASK、DJANGO、TORNADO,写爬虫有好用到哭的REQUESTS,还有强大到没盆友的SCRAPY 随着NUMPY、SCIPY、MATLOTLIB等众多第三方模块的开发和完善,不仅支持py支持各种数学运算,还可以绘制高质量的2D和3D图像&…...
Java中类和对象
类和对象 面向对象的认识类的定义和使用1 类的定义2 类的创建3 类的实例化 构造方法1 构造方法的概念2 构造方法的注意事项 this关键字 面向对象的认识 前言 何为面向对象何为面向过程呢?,C语言是最经典的面向过程的语言,但是C语言虽然可以解决一定的问…...
文本组件+Image组件+图集
Canvas部分知识补充 元素渲染顺序 以Hierarchy参考 下方物体在上方物体前显示 子物体在父物体前显示 下方物体永远在前显示,无论上方的层次结构 资源导入 绝对路径:C:\Windows\Fonts下的许多字体可以用做UIText的字体资源 图片导入: 1.图…...
Audacity 技术浅析(一)
Audacity 是一个开源的音频编辑工具,虽然它主要用于音频编辑和处理,但也可以通过一些插件和功能实现基本的音频生成功能。 1. Audacity 的音频生成基础 Audacity 的音频生成主要依赖于其内置的生成器、效果器以及 Nyquist 编程语言。这些工具允许用户创…...
PyCharm 2019.1.3使用python3.9创建虚拟环境setuptools-40.8.0报错处理
目录 前置: 一劳永逸方法(缺最后一步,没有成行) step one: 下载高版本的pip、setuptools、virtualenv的tar.gz包 step two: 进入PyCharm安装目录的 helpers 目录下 step three: 下载并安装grep和sed命令,然后执行 …...
敏捷开发在中小团队中的应用与挑战:实战指南与避坑手册
文章目录 敏捷开发在中小团队中的应用与挑战:实战指南与避坑手册引言:为什么中小团队更需要敏捷?一、敏捷开发适配中小团队的底层逻辑1.1 中小团队的典型特征1.2 敏捷开发的价值放大器效应 二、敏捷实施的五大实战步骤2.1 团队定制化改造&…...
服务器部署RocketMQ----Docker方式
拉取镜像并创建docker network 按照官方文档提供的方式拉取镜像:docker pull apache/rocketmq:4.9.6 创建一个docker网络:docker network create rocketmq 启动NameServer以及Broker 启动NameServer # 启动NameServer docker run -d --name rmqnames…...
【推荐项目】052-用水监控管理系统
052-用水监控管理系统 介绍 用水监控管理系统 springboot java vuejs jdk1.8 当然,以下是一个简洁的用水监控管理系统的功能模块划分,基于Spring Boot(JDK 1.8)后端和Vue.js前端: 用水监控管理系统功能模块 后端&…...
零基础上手Python数据分析 (2):Python核心语法快速入门
写在前面 场景:每周销售数据报表整理 任务描述: 你需要每周从多个Excel文件中汇总销售数据,计算各项指标(销售额、订单量、客单价等),并生成周报。Excel操作痛点: 文件太多,手动打开复制粘贴,效率低下,容易出错。 多个Excel文件,每个都要打开、筛选、复制数据,重复…...
大模型MCP协议与Function Calling:构建更智能的AI生态系统
随着大型语言模型(LLM)的快速发展,如何高效地将这些模型与外部数据源、工具和服务进行集成,成为了一个亟待解决的问题。Anthropic推出的Model Context Protocol(MCP协议)和Function Calling技术为此提供了有…...
【C++】RAII机制
什么是RAII机制? RAII(Resource Acquisition Is Initialization)是 C 中的一种重要编程范式,用于管理资源(如内存、文件句柄、网络连接等)的生命周期。 RAII 的核心思想是:资源的获取与初始化绑…...
游戏引擎学习第160天
回顾和今天的计划 我们没有使用任何游戏引擎和库,完全靠我们自己,使用的是老式的编程方式。 我们已经构建了很多内容,游戏引擎开发也慢慢接近尾声。现在我们已经接近完成了所有为支持游戏开发所需要的工作,接下来将逐步过渡到游戏…...
Webpack 知识点整理
1. 对 webpack 的理解?解决了什么问题? Webpack 是前端工程化领域的核心工具,其核心定位是模块打包器(Module Bundler),通过将各类资源(JS、CSS、图片等)视为模块并进行智能整合…...
从零搭建微服务项目Pro(第2-2章——JSR303自定义文件校验+整合至微服务公共模块)
前言: JSR 303,即 Bean Validation,是 Java EE 6 中的一项子规范,旨在为 Java Bean 提供一种标准化的数据验证机制。它通过注解的方式,允许开发者在 Java 类的字段或方法上直接定义验证规则,从而将验证逻辑…...
如何用URDF文件构建机械手模型并与MoveIt集成
机械手URDF文件的编写 我们用urdf文件来描述我们的机械手的外观以及物理性能。这里为了简便,就只用了基本的圆柱、立方体了。追求美观的朋友,还可以用dae文件来描述机械手的外形。 import re def remove_comments(text):pattern r<!--(.*?)-->…...
uv pip install -r requirements.txt-报错,python版本过低
升级Python版本(推荐) browser-use0.1.40 需要 Python ≥3.11,但你的环境是 Python 3.10.12。升级Python版本是最直接的解决方案: 安装Python 3.11: 使用 pyenv(Linux/macOS):pyenv…...
【训练细节解读】文本智能混合分块(Mixtures of Text Chunking,MoC)引领RAG进入多粒度感知智能分块阶段
喜欢本文可以在主页订阅专栏哟 核心创新:双重评估指标与混合分块架构: 第一章:检索增强生成(RAG)技术演进与分块挑战 1.1 RAG架构的核心演变 检索增强生成(Retrieval-Augmented Generation)…...
招聘信息|基于SprinBoot+vue的招聘信息管理系统(源码+数据库+文档)
招聘信息管理系统 目录 基于SprinBootvue的招聘信息管理系统 一、前言 二、系统设计 三、系统功能设计 5.1系统功能模块 5.2管理员功能模块 5.3企业后台管理模块 5.4用户后台管理模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、…...
HCIA-AI人工智能笔记1:大模型技术演进与发展历程
一、大模型发展的技术演进图谱 timelinetitle 大模型发展关键里程碑1958 : 感知机模型诞生(Frank Rosenblatt)1986 : BP反向传播算法(Rumelhart)2012 : AlexNet开启深度学习时代2017 : Transformer架构提出(《Attenti…...
躲藏博弈中的策略优化:整合历史数据、概率论与博弈论
躲藏博弈中的策略优化:整合历史数据、概率论与博弈论 一、引言 躲藏博弈(Hiding Games)作为一类特殊的博弈模型,广泛存在于军事对抗、网络安全、商业竞争甚至日常生活中。其核心在于一方(躲藏者)试图避免被另一方(寻找者)发现,双方各自选择…...
C语言,记录一次局部变量被意外修改的问题
背景:单片机开发过程中,我在函数体内(begin_face_record)定义了一个局部变量data_length,在使用的时候,该局部变量一直别改变,每次调用其他函数,例如c库里面的函数memcpy,不知什么情况data_length值就会被改变。 1、源码分析 void main(void) { init_gpio();init_fa…...
机器学习——正则化、欠拟合、过拟合、学习曲线
过拟合(overfitting):模型只能拟合训练数据的状态。即过度训练。 避免过拟合的几种方法: ①增加全部训练数据的数量(最为有效的方式) ②使用简单的模型(简单的模型学不够,复杂的模型学的太多&am…...
在微信小程序或前端开发中,picker 和 select 都是用户交互中用于选择的组件,但它们在功能、设计和使用场景上有一定的区别
在微信小程序或前端开发中,picker 和 select 都是用户交互中用于选择的组件,但它们在功能、设计和使用场景上有一定的区别。 1. picker 的特点 描述: picker 是微信小程序中的原生组件,通常用于选择单项或多项值,如时…...
向量数据库对比以及Chroma操作
一、向量数据库与传统类型数据库 向量数据库(Vector Storage Engine)与传统类型的数据库如关系型数据库(MySQL)、文档型数据库(MongoDB)、键值存储(Redis)、全文搜索引擎࿰…...
Python Matplotlib面试题精选及参考答案
绘制函数 y2x5 在区间 [1,10] 的折线图,设置标题和坐标轴标签 要绘制函数 y 2x 5 在区间 [1, 10] 的折线图,并设置标题和坐标轴标签,可借助 Python 的 matplotlib 库来实现。以下是详细的实现步骤与代码示例。 首先,要导入 mat…...
FiddlerScript学习笔记
参考官方文档:https://www.fiddlerbook.com/fiddler/dev/scriptsamples.asp json // 反序列化 static function jsonDecode(str : String){return Fiddler.WebFormats.JSON.JsonDecode(str).JSONObject; } // 序列化 static function jsonEncode(jsonObject : Obje…...
