反射机制的理解

一、getName 方法解析
代码功能
public static String getName(String key) throws IOException {Properties properties = new Properties();FileInputStream in = new FileInputStream("D:\\路径...\\application.properties");properties.load(in); // 加载配置文件内容in.close(); // 关闭流return properties.getProperty(key); // 根据 key 返回对应的值
}
作用

application.properties 配置文件中读取指定 key 的值(如 classNamemethodName)。

配置文件示例

假设 application.properties 内容如下:

# 定义要反射的类名和方法名
className=com.example.TestInvoke
methodName=printMessage
执行过程
  1. 加载文件:通过 FileInputStream 读取指定路径的配置文件。

  2. 解析配置Properties.load() 方法将文件内容解析为键值对。

  3. 获取值properties.getProperty("className") 返回 "com.example.TestInvoke"

代码问题
  1. 硬编码路径D:\\路径... 是绝对路径,实际项目应使用相对路径或类路径加载。

  2. 资源未安全关闭:若 load() 抛出异常,in.close() 可能不会执行,建议用 try-with-resources

  3. 异常处理简单:直接抛出 IOException,未处理文件不存在等具体问题。

改进版本
public static String getName(String key) {// 使用类路径加载(文件需放在 resources 目录下)try (InputStream in = YourClass.class.getClassLoader().getResourceAsStream("application.properties")) {Properties properties = new Properties();properties.load(in);return properties.getProperty(key);} catch (IOException e) {throw new RuntimeException("加载配置文件失败", e);}
}

二、反射机制详解
什么是反射?

反射(Reflection)是 Java 在 运行时 动态获取类信息并操作类的能力,包括:

  • 动态加载类

  • 创建对象

  • 调用方法

  • 访问私有成员

为什么需要反射?
  1. 解耦:代码不直接依赖具体类(如通过配置文件指定类名)。

  2. 灵活性:框架中自动装配对象(如 Spring 的 @Autowired)。

  3. 通用工具:如 JSON 序列化、单元测试调用私有方法。


三、结合代码理解反射流程
完整流程
1. 读取配置文件 → 2. 获取类名和方法名 → 3. 反射加载类 → 4. 创建对象 → 5. 调用方法
分步解析
  1. 读取配置 通过 getName("className") 获取 "com.example.TestInvoke"

  2. 加载类

    Class<?> c = Class.forName("com.example.TestInvoke");
    • JVM 动态加载该类到内存(如果尚未加载)。

  3. 创建实例

    TestInvoke obj = (TestInvoke) c.newInstance();
    • 相当于执行 new TestInvoke()(要求类有无参构造方法)。

  4. 获取并调用方法

    Method method = c.getDeclaredMethod("printMessage");
    method.invoke(obj);
    • 即使 printMessage 是私有方法,setAccessible(true) 后仍可调用。


四、反射核心 API
操作API 示例作用
加载类Class.forName("全限定类名")获取类的 Class 对象
创建实例clazz.newInstance()clazz.getConstructor().newInstance()实例化对象
获取方法clazz.getMethod("方法名", 参数类型...)获取公开方法
获取私有方法clazz.getDeclaredMethod("方法名") + setAccessible(true)访问私有方法
调用方法method.invoke(实例对象, 参数...)执行方法

五、示例:从配置到反射的完整过程
1. 配置文件 application.properties
className=com.example.UserService
methodName=login
2. 目标类 UserService
package com.example;
​
public class UserService {private void login() {System.out.println("用户登录成功!");}
}
3. 反射调用代码
public static void main(String[] args) {try {// 从配置读取类名和方法名String className = getName("className"); // "com.example.UserService"String methodName = getName("methodName"); // "login"
​// 反射操作Class<?> clazz = Class.forName(className);Method method = clazz.getDeclaredMethod(methodName);method.setAccessible(true);Object instance = clazz.getDeclaredConstructor().newInstance();method.invoke(instance); // 输出:"用户登录成功!"} catch (Exception e) {e.printStackTrace();}
}

六、反射的注意事项
  1. 性能开销:反射比直接调用慢,频繁调用需谨慎。

  2. 安全限制:模块化系统中(Java 9+)可能禁止访问私有成员。

  3. 破坏封装:反射可以绕过访问修饰符,滥用会导致代码难以维护。

  4. 类型安全:编译时无法检测类型错误,需自行保证类型正确性。


七、常见应用场景
  1. 框架开发:如 Spring 的依赖注入、MyBatis 的 Mapper 动态代理。

  2. 动态加载插件:通过配置文件指定实现类。

  3. 单元测试:测试私有方法(不推荐,但有时必要)。

  4. 通用工具:如通过反射实现对象拷贝、序列化工具。


总结
  • 通过 配置文件 解耦了类名和方法名的硬编码,利用 反射 实现了动态调用。

  • 反射是 Java 强大的特性,但需谨慎使用。理解其原理后,可以更深入掌握框架设计思想(如 Spring 的核心机制)。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Visual studio + Qt 项目配置管理

Visual studio Qt 项目配置管理 1.本机顺利安装 vs 和 Qt 软件 ​ 并且设置好Qt 的环境变量比如 E:\Qt\Qt5.9.8\5.9.8\msvc2017_64\bin E:\Qt\Qt5.9.8\5.9.8\msvc2017_64\lib E:\Qt\Qt5.9.8\5.9.8\msvc2017_64\include //这里是你电脑上Qt的路径&#xff0c;每台电脑不一样…

通过 Python 爬虫提高股票选股胜率

此贴为Python爬虫技术学习贴 在股票中&#xff0c;即便有了选股规则&#xff0c;从5000多只股票中筛选出符合规则的股票也是十分困难的&#xff0c;于是想通过爬虫来实现自动化的快速选股。全文用GP代替股票 实现方案 1、指定两套规则&#xff0c;第一套弱约束&#xff0c;第…

SpringCloud带你走进微服务的世界

认识微服务 随着互联网行业的发展&#xff0c;对服务的要求也越来越高&#xff0c;服务架构也从单体架构逐渐演变为现在流行的微服务架构。这些架构之间有怎样的差别呢&#xff1f; 单体架构 单体架构&#xff1a;将业务的所有功能集中在一个项目中开发&#xff0c;打成一个…

FastAPI复杂查询终极指南:告别if-else的现代化过滤架构

title: FastAPI复杂查询终极指南:告别if-else的现代化过滤架构 date: 2025/3/14 updated: 2025/3/14 author: cmdragon excerpt: 本文系统讲解FastAPI中复杂查询条件的构建方法,涵盖参数验证、动态过滤、安全防护等18个核心技术点。通过引入策略模式、声明式编程等技术,彻…

Ubuntu 22.04使用pigz多线程快速解压/压缩文件

最近搞项目&#xff0c;资料太大&#xff0c;解压时间太久&#xff0c;于是想办法解决。 开贴记录。 1.安装pigz sudo apt install pigz 2.解压资料 解压命令为 tar --use-compress-programpigz -xvpf ***.tar.gz 将最后的部分***.tar.gz换成你自己的文件即可 例如 ti…

Amazon Quantum Ledger Database (QLDB):革新数据可信记录的终极解决方案

在数字化浪潮中&#xff0c;企业数据的安全性与可信性成为核心挑战。无论是金融交易的透明审计、供应链的全程追踪&#xff0c;还是医疗记录的真实性验证&#xff0c;如何确保数据不可篡改且可追溯&#xff0c;已成为企业亟待解决的难题。Amazon Quantum Ledger Database (QLDB…

日本IT|AWS工作内容及未来性、以及转职的所需资质和技能

AWSとは AWSはAmazon Web Services&#xff08;アマゾンウェブサービス&#xff09;の略称です。 名称から分かるとおり、ネットを通じた通販などを事業として行っているAmazon.com社がクラウドサービスとして運営しています。 本来であれば自分たちでインフラ環境を構築する…

Conda+jupyterlab

文章目录 1、Conda1.1、基本介绍1.2、conda安装1.3、conda常用命令1.3.1、基本命令1.3.2、环境管理 2、Jupyterlab2.1、基本介绍2.2、安装使用 3、pycharm中使用conda 1、Conda 1.1、基本介绍 Conda 是一个开源的包管理和环境管理工具&#xff0c;适用于 Python 及其他编程语…

Vue 项目中 CDN 引入的利弊及解决方案

在Vue项目中&#xff0c;引入到工程中的所有js、css文件&#xff0c;编译时都会被打包进vendor.js&#xff0c;浏览器在加载该文件之后才能开始显示首屏。若是引入的库众多&#xff0c;那么vendor.js文件体积将会相当的大&#xff0c;影响首屏的体验。通过调试发送时间主要消耗…

拥有一台云服务器能做什么呢?

拥有一台云服务器就像拥有了一台24小时在线的远程电脑&#xff0c;你可以通过互联网随时随地管理它。它的用途非常广泛&#xff0c;无论是个人学习、开发测试&#xff0c;还是企业级应用部署&#xff0c;都能发挥重要作用。以下是常见的应用场景&#xff0c;按需求分类整理&…

PHP 在 if 判断时由于运算符优先级导致 false 的问题

首先来看一段代码&#xff1a; $price 187.50;if (!is_numeric($price) || $price < 0 || ($price * 100 > 1000000)) {echo "价格错误&#xff1a;$price\n"; } else {echo "价格正确&#xff1a;$price\n"; }乍一看是不是认为并没有什么问题&…

从零基础到能独立设计单片机产品,一般需要经历哪些学习阶段?

相信很多人&#xff0c;内心都有“钢铁侠”的幻想&#xff0c;成为能写程序&#xff0c;能设计硬件&#xff0c;能设计结构&#xff0c;能焊接的全能型人才。 上次徐工问我&#xff0c;如果你财富自由了&#xff0c;想去做啥&#xff1f; 我说出来&#xff0c;可能大家都不信&a…

Liunx启动kafka并解决kafka时不时挂掉的问题

kafka启动步骤 先启动zookeeper&#xff0c;启动命令如下 nohup ./zookeeper-server-start.sh /home/kafka/kafka/config/zookeeper.properties > /home/kafka/kafka/zookeeper.log 2>&1 &再启动kafka&#xff0c;启动命令如下 nohup ./kafka-server-start.sh…

使用STM32CubeMX配置定时器中断实现LED每秒闪烁一次(STM32G070CBT6)

说明&#xff1a; 本案例采用的定时器3&#xff08;TIM3&#xff09;实现&#xff0c;使用其他定时器是一样配置。 如何新建一个工程以及如何配置LED的端口&#xff0c;请查看前面文章&#xff1a;使用STM32CubeMX实现LED灯每秒闪烁一次&#xff08;STM32G070CBT6单片机&…

暴力破解Excel受保护的单元格密码

暴力破解Excel受保护的单元格密码 分享一个暴力破解Excel受保护的单元格密码的方法 第一步 在Excel中按下Alt F11&#xff0c;打开Visual Basic for Applications&#xff08;VBA&#xff09;编辑器。 第二步 在VBA编辑器中&#xff0c;点击插入菜单&#xff0c;选择模块…

Git常用操作之GitLab

Git常用操作之GitLab 小薛博客官网&#xff1a;小薛博客Git常用操作之GitLab官方地址 1、GitLab安装 https://gitlab.cn/install/ 1、Docker安装GitLab https://docs.gitlab.cn/jh/install/docker.html 1、设置卷位置 在设置其他所有内容之前&#xff0c;请配置一个新的…

pgsql创建新用户并赋只读权限

在 PostgreSQL 中&#xff0c;为新用户赋予只读权限的步骤如下&#xff1a; —### 1. 创建新用户首先&#xff0c;创建一个新用户&#xff08;角色&#xff09;&#xff0c;并设置密码&#xff1a;sqlCREATE ROLE 用户名 WITH LOGIN PASSWORD 密码;例如&#xff1a;sqlCREATE R…

数据结构与算法——算法3 面试常用排序算法

首先了解排序算法性能和优缺点 然后了解快排 和堆排序的方法。 可以参考如下的博客 八大排序(超详解附动图源码)

linux root丢失修改密

在RHEL7下重置密码 第一种方式&#xff1a;光驱进入急救模式 //做之前最好 selinuxdisabled Conntinue 然后chroot /mnt/sysimag 然后编辑/etc/shadow文件 第二种方式&#xff1a; 1&#xff1a;编辑启动菜单按e,找到linux16行&#xff0c;在行尾加入 init/bin/sh,同时在…

数据类设计_图片类设计之3_半规则图类设计(前端架构基础)

前言 学的东西多了,要想办法用出来.C和C是偏向底层的语言,直接与数据打交道.尝试做一些和数据方面相关的内容 引入 接续上一篇讨论半规则图类型的设计 半规则图的定义 什么是半规则图?笔者看见了一些似乎规则又不是太规则的图形,例如带圆角的矩阵,在页面上找一个圆角框 为了…