news 2026/6/10 15:31:06

(20)回顾反射机制

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
(20)回顾反射机制

分析方法四要素

我们先来看一下,不使用反射机制调用一个方法需要几个要素的参与。
有一个这样的类:

packagecom.powernode.reflect;/** * @author 动力节点 * @version 1.0 * @className SystemService * @since 1.0 **/publicclassSystemService{publicvoidlogout(){System.out.println("退出系统");}publicbooleanlogin(Stringusername,Stringpassword){if("admin".equals(username)&&"admin123".equals(password)){returntrue;}returnfalse;}}

编写程序调用方法:

packagecom.powernode.reflect;/** * @author 动力节点 * @version 1.0 * @className ReflectTest01 * @since 1.0 **/publicclassReflectTest01{publicstaticvoidmain(String[]args){// 创建对象SystemServicesystemService=newSystemService();// 调用方法并接收方法的返回值booleansuccess=systemService.login("admin","admin123");System.out.println(success?"登录成功":"登录失败");}}

通过以上第16行代码可以看出,调用一个方法,一般涉及到4个要素:

  • 调用哪个对象的(systemService)
  • 哪个方法(login)
  • 传什么参数(“admin”, “admin123”)
  • 返回什么值(success)

获取Method

要使用反射机制调用一个方法,首先你要获取到这个方法。
在反射机制中Method实例代表的是一个方法。那么怎么获取Method实例呢?
有这样一个类:

packagecom.powernode.reflect;/** * @author 动力节点 * @version 1.0 * @className SystemService * @since 1.0 **/publicclassSystemService{publicvoidlogout(){System.out.println("退出系统");}publicbooleanlogin(Stringusername,Stringpassword){if("admin".equals(username)&&"admin123".equals(password)){returntrue;}returnfalse;}publicbooleanlogin(Stringpassword){if("110".equals(password)){returntrue;}returnfalse;}}

我们如何获取到 logout()、login(String,String)、login(String) 这三个方法呢?
要获取方法Method,首先你需要获取这个类Class。

Classclazz=Class.forName("com.powernode.reflect.SystemService");

当拿到Class之后,调用getDeclaredMethod()方法可以获取到方法。
假如你要获取这个方法:login(String username, String password)

MethodloginMethod=clazz.getDeclaredMethod("login",String.class,String.class);

假如你要获取到这个方法:login(String password)

MethodloginMethod=clazz.getDeclaredMethod("login",String.class);

获取一个方法,需要告诉Java程序,你要获取的方法的名字是什么,这个方法上每个形参的类型是什么。这样Java程序才能给你拿到对应的方法。
这样的设计也非常合理,因为在同一个类当中,方法是支持重载的,也就是说方法名可以一样,但参数列表一定是不一样的,所以获取一个方法需要提供方法名以及每个形参的类型。
假设有这样一个方法:

publicvoidsetAge(intage){this.age=age;}

你要获取这个方法的话,代码应该这样写:

MethodsetAgeMethod=clazz.getDeclaredMethod("setAge",int.class);

其中setAge是方法名,int.class是形参的类型。
如果要获取上面的logout方法,代码应该这样写:

MethodlogoutMethod=clazz.getDeclaredMethod("logout");

因为这个方法形式参数的个数是0个。所以只需要提供方法名就行了。你学会了吗?

调用Method

要让一个方法调用的话,就关联到四要素了:

  • 调用哪个对象的
  • 哪个方法
  • 传什么参数
  • 返回什么值
packagecom.powernode.reflect;/** * @author 动力节点 * @version 1.0 * @className SystemService * @since 1.0 **/publicclassSystemService{publicvoidlogout(){System.out.println("退出系统");}publicbooleanlogin(Stringusername,Stringpassword){if("admin".equals(username)&&"admin123".equals(password)){returntrue;}returnfalse;}publicbooleanlogin(Stringpassword){if("110".equals(password)){returntrue;}returnfalse;}}

假如我们要调用的方法是:login(String, String)
第一步:创建对象(四要素之首:调用哪个对象的)

Classclazz=Class.forName("com.powernode.reflect.SystemService");Objectobj=clazz.newInstance();//过时方法

第二步:获取方法login(String,String)(四要素之一:哪个方法)

MethodloginMethod=clazz.getDeclaredMethod("login",String.class,String.class);

第三步:调用方法

ObjectretValue=loginMethod.invoke(obj,"admin","admin123");

解说四要素:

  • 哪个对象:obj
  • 哪个方法:loginMethod
  • 传什么参数:“admin”, “admin123”
  • 返回什么值:retValue
packagecom.powernode.reflect;importjava.lang.reflect.Method;/** * @author 动力节点 * @version 1.0 * @className ReflectTest02 * @since 1.0 **/publicclassReflectTest02{publicstaticvoidmain(String[]args)throwsException{Classclazz=Class.forName("com.powernode.reflect.SystemService");Objectobj=clazz.newInstance();MethodloginMethod=clazz.getDeclaredMethod("login",String.class,String.class);ObjectretValue=loginMethod.invoke(obj,"admin","admin123");System.out.println(retValue);}}

那如果调用既没有参数,又没有返回值的logout方法,应该怎么做?

packagecom.powernode.reflect;importjava.lang.reflect.Method;/** * @author 动力节点 * @version 1.0 * @className ReflectTest03 * @since 1.0 **/publicclassReflectTest03{publicstaticvoidmain(String[]args)throwsException{Classclazz=Class.forName("com.powernode.reflect.SystemService");Objectobj=clazz.newInstance();MethodlogoutMethod=clazz.getDeclaredMethod("logout");logoutMethod.invoke(obj);}}

假设你知道属性名

假设有这样一个类:

packagecom.powernode.reflect;/** * @author 动力节点 * @version 1.0 * @className User * @since 1.0 **/publicclassUser{privateStringname;privateintage;publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.name=name;}publicintgetAge(){returnage;}publicvoidsetAge(intage){this.age=age;}@OverridepublicStringtoString(){return"User{"+"name='"+name+'\''+", age="+age+'}';}}

你知道以下这几条信息:

  • 类名是:com.powernode.reflect.User
  • 该类中有String类型的name属性和int类型的age属性。
  • 另外你也知道该类的设计符合javabean规范。(也就是说属性私有化,对外提供setter和getter方法)

你如何通过反射机制给User对象的name属性赋值zhangsan,给age属性赋值20岁。

packagecom.powernode.reflect;importjava.lang.reflect.Method;/** * @author 动力节点 * @version 1.0 * @className UserTest * @since 1.0 **/publicclassUserTest{publicstaticvoidmain(String[]args)throwsException{// 已知类名StringclassName="com.powernode.reflect.User";// 已知属性名StringpropertyName="age";// 通过反射机制给User对象的age属性赋值20岁Class<?>clazz=Class.forName(className);Objectobj=clazz.newInstance();// 创建对象// 根据属性名获取setter方法名StringsetMethodName="set"+propertyName.toUpperCase().charAt(0)+propertyName.substring(1);// 获取MethodMethodsetMethod=clazz.getDeclaredMethod(setMethodName,int.class);// 调用MethodsetMethod.invoke(obj,20);System.out.println(obj);}}

执行结果:
给User的name属性赋值zhangsan,这个大家可以尝试自己完成哦!!!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 2:01:15

Vue的Class绑定对象语法如何让动态类名切换变得直观高效?

url: /posts/a9e7ed9dc135b1dc2120fda6242905a1/ title: Vue的Class绑定对象语法如何让动态类名切换变得直观高效? date: 2025-12-14T08:10:27+08:00 lastmod: 2025-12-14T08:10:27+08:00 author: cmdragon cover: /images/exbix_00026_.png summary: Vue的Class绑定对象语法…

作者头像 李华
网站建设 2026/6/10 11:33:52

内存条电压

内存条1.35V和1.5V的核心区别在于工作电压不同&#xff0c;直接影响功耗、发热、兼容性及适用场景。1.35V属于低电压版&#xff08;DDR3L&#xff09;&#xff0c;而1.5V是标准电压版&#xff08;DDR3&#xff09;。 内存条的电压通常取决于其类型和规格。常见的DDR4内存条标准…

作者头像 李华
网站建设 2026/6/9 22:48:38

服务器内存条与工作站内存条区别

兼容性核心差异服务器内存&#xff08;如RDIMM&#xff09;与台式机内存&#xff08;UDIMM&#xff09;在设计和功能上存在本质区别&#xff1a;‌物理接口不匹配‌&#xff1a;服务器内存&#xff08;如LRDIMM&#xff09;金手指数量、缺口位置与台式机内存不同&#xff0c;强…

作者头像 李华
网站建设 2026/6/10 11:34:38

中国以食物命名的城市:地域文化与自然馈赠的诗意联结——全国排名第一起名大师颜廷利教授的深度解读

中国以食物命名的城市&#xff1a;地域文化与自然馈赠的诗意联结 ——全国排名第一起名大师颜廷利教授的深度解读在中国广袤的版图上&#xff0c;城市名称不仅是地理标识&#xff0c;更承载着深厚的历史文化与自然智慧。全国权威起名大师颜廷利教授指出&#xff0c;许多城市以食…

作者头像 李华
网站建设 2026/6/10 11:34:36

25、文本处理工具全解析

文本处理工具全解析 在文本处理的世界里,有许多实用的工具能帮助我们高效地完成各种任务,如文件打补丁、字符转换、文本编辑和拼写检查等。下面将详细介绍这些工具及其使用方法。 文件打补丁:patch 工具 当我们创建了 diff 文件后,就可以使用 patch 工具将旧文件更新为…

作者头像 李华
网站建设 2026/6/10 14:50:34

轻量级AI模型本地化部署终极指南:3步搞定60M参数T5模型

轻量级AI模型本地化部署终极指南&#xff1a;3步搞定60M参数T5模型 【免费下载链接】t5_small T5-Small is the checkpoint with 60 million parameters. 项目地址: https://ai.gitcode.com/openMind/t5_small 还在为AI模型部署的复杂流程而头疼吗&#xff1f;今天我们将…

作者头像 李华