当前位置: 首页 > news >正文

框架专题:反射

1. 什么是反射?

简单来说,反射是一种程序自省的能力,即在程序运行时动态地获取其结构信息或操作其行为。这包括类、方法、属性等元信息。反射的核心在于让代码变得更加动态化,从而突破静态语言的限制。

以Java为例,反射允许你:

  • 动态获取一个类的名称、字段、方法、构造函数等信息;
  • 创建类的实例;
  • 调用类的方法或访问类的字段;
  • 修改类的行为。

示例代码

以下是一段使用Java反射的示例代码:

import java.lang.reflect.Method;public class ReflectionDemo {public static void main(String[] args) throws Exception {Class<?> clazz = Class.forName("java.util.ArrayList");Object instance = clazz.getDeclaredConstructor().newInstance();Method addMethod = clazz.getMethod("add", Object.class);addMethod.invoke(instance, "Hello Reflection");System.out.println(instance); // 输出: [Hello Reflection]}
}

在上面的代码中,我们通过反射动态创建了ArrayList实例,并调用其add方法加入了一个元素。


2. 为什么要使用反射?

反射的主要作用体现在以下几个方面:

2.1 提高代码灵活性

反射允许框架开发者编写能够适配不同需求的通用代码。例如,在ORM(对象关系映射)框架中,可以通过反射动态解析实体类和数据库表的映射关系。

2.2 动态加载和执行代码

反射使程序能够在运行时根据用户需求加载不同的模块或插件,而无需提前知道它们的具体实现。例如,Spring框架通过反射动态创建和管理Bean对象。

2.3 元编程能力

反射为程序提供了操作自身结构的能力,从而实现高效的工具开发,如动态代理、注解处理器等。


3. 反射的典型使用场景

3.1 框架开发

几乎所有的主流框架都离不开反射的使用。以下是几个典型应用:

  • Spring:通过反射动态扫描类路径,加载符合条件的Bean;
  • Hibernate:通过反射解析实体类的注解,生成SQL语句。
  • MyBatis:MyBatis 大量使用反射技术来实现以下功能:
    • SQL语句的动态解析:通过反射读取Mapper接口中定义的方法信息,将其与SQL映射文件的内容动态绑定。
    • 结果映射:通过反射将查询结果的字段值动态注入到目标实体类的属性中。
    • 方法代理:利用动态代理和反射技术,实现Mapper接口的方法调用与底层执行逻辑的解耦。

3.2 插件机制

插件机制的实现依赖于程序能够动态加载和调用未知模块。例如,浏览器可以通过反射加载第三方插件。

3.3 动态代理

Java的Proxy类和C#的DynamicObject都依赖于反射实现动态代理,常用于AOP(面向切面编程)。


4. 反射的实际案例分析

案例:自定义注解解析

假设我们需要开发一个简单的框架,通过注解实现方法权限检查。

步骤1:定义注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RequiresPermission {String value();
}
步骤2:编写目标类
public class UserService {@RequiresPermission("admin")public void deleteUser() {System.out.println("User deleted");}public void addUser() {System.out.println("User added");}
}
步骤3:实现注解解析逻辑
import java.lang.reflect.Method;public class PermissionChecker {public static void checkPermissions(Object object) throws Exception {Method[] methods = object.getClass().getMethods();for (Method method : methods) {if (method.isAnnotationPresent(RequiresPermission.class)) {RequiresPermission annotation = method.getAnnotation(RequiresPermission.class);String requiredPermission = annotation.value();if (!"admin".equals(requiredPermission)) { // 模拟权限检查throw new SecurityException("Permission denied for method: " + method.getName());}method.invoke(object); // 调用方法}}}public static void main(String[] args) throws Exception {UserService userService = new UserService();checkPermissions(userService); // 检查权限并执行方法}
}
输出

如果权限检查通过,deleteUser方法会被执行;否则抛出权限不足异常。


5. 反射的注意事项

5.1 性能开销

反射操作通常比直接调用慢,主要原因是:

  • 缺少编译时优化;
  • 方法调用需要额外的安全检查。

因此,在性能敏感的场景下,应尽量避免频繁使用反射。

5.2 安全性风险

反射突破了语言访问控制的限制,可能导致敏感数据被暴露或修改。开发时应严格控制反射操作的权限。

5.3 可维护性

过度依赖反射会增加代码的复杂性和调试难度,应合理权衡其使用场景。


6. 总结

反射是框架开发中不可或缺的工具,为程序提供了运行时的灵活性和动态化能力。通过反射,我们可以实现诸如动态代理、注解处理、插件机制等功能。然而,反射并非万能,开发者在使用时需要权衡性能、安全性和可维护性,以确保代码质量。希望通过本文的介绍,大家能更好地理解和应用反射,为自己的项目增添更多可能性!

相关文章:

框架专题:反射

1. 什么是反射&#xff1f; 简单来说&#xff0c;反射是一种程序自省的能力&#xff0c;即在程序运行时动态地获取其结构信息或操作其行为。这包括类、方法、属性等元信息。反射的核心在于让代码变得更加动态化&#xff0c;从而突破静态语言的限制。 以Java为例&#xff0c;反…...

【Go】context标准库

文章目录 1. 概述1.1 什么是 Context1.2 设计原理1.3 使用场景源码分析核心:Context接口4个实现6个方法TODO 和 BackgroundWithCancelcancelpropagateCancel 绑定父对象WithTimeout 和 WithDeadlineWithValue总结参考1. 概述 基于版本: go1.22.3/src/context/context.go 1.1…...

LLMs之o3:《Deliberative Alignment: Reasoning Enables Safer Language Models》翻译与解读

LLMs之o3&#xff1a;《Deliberative Alignment: Reasoning Enables Safer Language Models》翻译与解读 导读&#xff1a;2024年12月&#xff0c;这篇论文提出了一种名为“审慎式对齐 (Deliberative Alignment)”的新方法&#xff0c;旨在提高大型语言模型 (LLM) 的安全性。论…...

git设置项目远程仓库指向github的一个仓库

要将你的Git项目设置为指向GitHub上的远程仓库&#xff0c;你需要执行以下步骤&#xff1a; 创建GitHub仓库&#xff1a; 登录到你的GitHub账户。点击右上角的 “” 号&#xff0c;选择 “New repository” 创建一个新的仓库。填写仓库的名称&#xff0c;可以添加描述&#xff…...

实战演练JDK的模块化机制

实战演练JDK的模块化机制--楼兰 带你聊最纯粹的Java ​ 你发任你发,我用Java8。你用的JDK到什么版本了?很多开源框架都已经开始陆续升级JDK版本了。你对于JDK8往后陆陆续续更新的这些版本有什么感觉吗? ​ 很多人会说其实并没有太多的感觉。JDK的新版本不断推出一些不痛不痒…...

jdk17+springboot3项目加密部署

最近项目需要在第三方服务器部署&#xff0c;由于没有交付源码。所以需要将项目加密后再部署。 网上找了一圈&#xff0c;发现xjar这个开源项目&#xff0c;可以将代码加密后进行部署。看了下正是我需要的。 于是按照文档打包加密&#xff0c;但启动的时候居然报错。 这个结…...

rm -rf 删除/下bin lib lib64 sbin软链接系统恢复

背景 不小心删除了/bin、/lib、/lib64和/sbin这些目录的软链接&#xff0c;导致系统中的各种命令都无法正常使用。在尝试多种方法后&#xff0c;包括添加环境变量和使用绝对路径执行命令无法恢复&#xff0c;最终不重装完美解决。 [rootcentos-8 /]# ll 总用量 36 drwxr-xr-x …...

并发与竞争

并发与竞争 并发与竞争的产生 Linux是一个多任务操作系统&#xff0c;肯定会存在多个任务共同操作同一段内存或者设备的情况&#xff0c;多个任务甚至中断都能访问的资源叫做共享资源&#xff0c;就和共享单车一样。在驱动开发中要注意对共享资源的保护&#xff0c;也就是要处…...

Java后端开发 ”Bug“ 分享——订单与优惠卷

“优惠券风波”&#xff1a;一段代码引发的线上事故 起因&#xff1a;优惠券功能上线 故事的开始源于公司新上线的一项促销活动——在用户未使用优惠券时&#xff0c;系统会自动赠送一张优惠券。这个功能不仅能提升用户体验&#xff0c;还能拉动平台的销售额。为了赶上活动上…...

Linux系统之tee命令的基本使用

Linux系统之tee命令的基本使用 一、tee命令介绍二、tee命令的使用帮助2.1 tee命令的help帮助2.2 tee命令帮助解释 三、tee命令的基本使用3.1 写入文件3.2 追加文件3.3 结合sudo命令3.4 结合EOF使用 四、注意事项 一、tee命令介绍 tee 是 Linux 和 Unix 系统中的一个命令&#x…...

idea 8年使用整理

文章目录 前言idea 8年使用整理1. 覆盖application配置2. 启动的时候设置编辑空间大小&#xff0c;并忽略最大空间3. 查询类的关系4. 查看这个方法的引用关系5. 查看方法的调用关系5.1. 查看被调用关系5.2. 查看调用关系 6. 方法分隔线7. 选择快捷键类型8. 代码预览插件9. JReb…...

多个微服务 Mybatis 过程中出现了Invalid bound statement (not found)的特殊问题

针对多个微服务的场景&#xff0c;记录一下这个特殊问题&#xff1a; 如果启动类上用了这个MapperScan注解 在resource 目录下必须建相同的 com.demo.biz.mapper 目录结构&#xff0c;否则会加载不到XML资源文件 。 并且切记是com/demo/biz 这样的格式创建&#xff0c;不要使用…...

k8s,service如何找到容器

Kubernetes之所以需要Service&#xff0c;一方面是因为Pod的IP不是固定的&#xff0c;另一方面则是因为一组Pod实例之间总会有负载均衡的需求 被selector选中的Pod&#xff0c;就称为Service的Endpoints&#xff0c;查看方式&#xff1a; kubectl get endpoints hostnames需要…...

观察者模式和发布-订阅模式有什么异同?它们在哪些情况下会被使用?

大家好&#xff0c;我是锋哥。今天分享关于【观察者模式和发布-订阅模式有什么异同&#xff1f;它们在哪些情况下会被使用&#xff1f;】面试题。希望对大家有帮助&#xff1b; 观察者模式和发布-订阅模式有什么异同&#xff1f;它们在哪些情况下会被使用&#xff1f; 1000道 …...

docker compose deploy fate cluster

官方文档 写的不清晰 KubeFATE&#xff0c;用于生成部署脚本&#xff0c;链接 部署机就是下载了 KubeFATE的主机&#xff1b;运行机就是要安装fate容器的主机&#xff08;部署机和运行机可以相同&#xff09; 两个主机&#xff1a;并非必须 centos7&#xff0c;Ubuntu也行Doc…...

字节跳动Java开发面试题及参考答案(数据结构算法-手撕面试题)

怎么判断两个链表是否相交?怎么优化? 判断两个链表是否相交可以采用多种方法。 一种方法是使用双指针。首先分别遍历两个链表,得到两个链表的长度。然后让长链表的指针先走两个链表长度差的步数。之后,同时移动两个链表的指针,每次比较两个指针是否指向相同的节点。如果指…...

网工日记:FTP工作模式

FTP 基本概念 FTP&#xff08;File Transfer Protocol&#xff09;即文件传输协议&#xff0c;是用于在网络上进行文件传输的标准协议。它运行在 TCP/IP 协议栈之上&#xff0c;采用客户端 - 服务器&#xff08;C/S&#xff09;架构&#xff0c;通过在客户端和服务器之间建立控…...

unity使用代码在动画片段中添加event

unity使用代码在动画片段中添加event using UnityEngine;public static class AnimationHelper {/// <summary>/// 获取Animator状态对应的动画片段/// </summary>/// <param name"animator">Animator组件</param>/// <param name"…...

嵌入式轻量级开源操作系统:HeliOS的使用

嵌入式轻量级开源操作系统:HeliOS的使用 &#x1f4cd;项目地址&#xff1a;https://github.com/heliosproj/HeliOS HeliOS项目是一个社区交付的开源项目&#xff0c;用于构建和维护HeliOS嵌入式操作系统&#xff08;OS&#xff09;。HeliOS是一个功能齐全的操作系统&#xff0…...

解决VMware的ubuntu22虚拟机没有网络

解决步骤 1.在 Windows 系统中&#xff0c;按 “WinR” 键&#xff0c;输入 “services.msc” 并回车&#xff0c;在服务列表中找到 “VMware DHCP Service” 和 “VMware NAT Service”&#xff0c;确保这两个服务已启动&#xff0c;若未启动则右键点击选择 “启动”&#xf…...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段&#xff1a; 构建阶段&#xff08;Build Stage&#xff09;&#xff1a…...

Java 二维码

Java 二维码 **技术&#xff1a;**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...

Unity中的transform.up

2025年6月8日&#xff0c;周日下午 在Unity中&#xff0c;transform.up是Transform组件的一个属性&#xff0c;表示游戏对象在世界空间中的“上”方向&#xff08;Y轴正方向&#xff09;&#xff0c;且会随对象旋转动态变化。以下是关键点解析&#xff1a; 基本定义 transfor…...

基于鸿蒙(HarmonyOS5)的打车小程序

1. 开发环境准备 安装DevEco Studio (鸿蒙官方IDE)配置HarmonyOS SDK申请开发者账号和必要的API密钥 2. 项目结构设计 ├── entry │ ├── src │ │ ├── main │ │ │ ├── ets │ │ │ │ ├── pages │ │ │ │ │ ├── H…...

Go爬虫开发学习记录

Go爬虫开发学习记录 基础篇&#xff1a;使用net/http库 Go的标准库net/http提供了完善的HTTP客户端功能&#xff0c;是构建爬虫的基石&#xff1a; package mainimport ("fmt""io""net/http" )func fetchPage(url string) string {// 创建自定…...

LSTM-XGBoost多变量时序预测(Matlab完整源码和数据)

LSTM-XGBoost多变量时序预测&#xff08;Matlab完整源码和数据&#xff09; 目录 LSTM-XGBoost多变量时序预测&#xff08;Matlab完整源码和数据&#xff09;效果一览基本介绍程序设计参考资料 效果一览 基本介绍 普通的多变量时序已经用腻了&#xff0c;审稿人也看烦了&#…...

稻米分类和病害检测数据集(猫脸码客第237期)

稻米分类图像数据集&#xff1a;驱动农业智能化发展的核心资源 引言 在全球农业体系中&#xff0c;稻米作为最关键的粮食作物之一&#xff0c;其品种多样性为人类饮食提供了丰富选择。然而&#xff0c;传统稻米分类方法高度依赖人工经验&#xff0c;存在效率低、主观性强等缺…...

vue3 vite.config.js 引入bem.scss文件报错

[sass] Can’t find stylesheet to import. ╷ 1 │ use “/bem.scss” as *; │ ^^^^^^^^^^^^^^^^^^^^^^ ╵ src\App.vue 1:1 root stylesheet 分析 我们遇到了一个在Vue3项目中使用Vite时&#xff0c;在vite.config.js中引入bem.scss文件报错的问题。错误信息指出在App.vue…...

浏览器兼容-polyfill-本地服务-优化

babel和webpack结合 npx babel src --out-dir dist --presetsbabel/preset-env 这是把src下面的东西都用babel转化一下 webpack可以和babel结合使用&#xff0c;首先下载一个这东西&#xff1a; npm install babel-loader -D webpack配置&#xff1a; const path requir…...