第十天:Java反射

article/2025/7/13 8:47:04

反射

反射就是:加载类,并编写代码获取类中的成员变量,方法,构造器等。

注意:反射,注解,动态代理就是用来学习框架做框架的,在平时业务开发需求上很少用到。

1 反射学什么?

2 获取Class对象的三种方式

2.1 通过类名.class获取

Class c1=类名.class

Class c1=Student.class;
System.out.println(c1.getName());//全类名=包名+类名
System.out.println(c1.getSimpleName());//简名

2.2 通过Class提供的方法forName()

Class.forName(“填自己想获得的类的全类名”)

Class c2=Class.forName("com.xie.Student");

2.3 通过对象提供的方法

Class c3=对象.getClass()

Student student=new Student();
Class c3=student.getClass();

3 获取类的构造器

3.1 getConstructors()

获取所有公共构造函数(在开发中一般不会用这个)

Class c1=Cat.class;
Constructor[] cons=c1.getConstructors();

3.2 getDeclaredConstructors()

获取所有构造函数,可以是公共、私有或受保护的构造函数。(开发中推荐使用)

Class c2=Cat.class;
Constructor[] cons=c2.getDeclaredConstructors();

3.3 getConstructor(Class<?>… parameterTypes)

获取指定参数类型的公共构造函数

Class c1=Cat.class;
Constructor constructor=c1.getConstructor();

3.4 getDeclaredConstructor(Class<?>… parameterTypes)

获取指定参数类型的构造函数,可以是公共、私有或受保护的构造函数(推荐)

Class c2=Cat.class;
Constructor constructor=c2.getDeclaredConstructor(String.class,int.class);

4 获取类的构造器的作用

作用:初始化对象并返回

4.1 初始化对象newInstance(参数)

调用此构造器对象表示的构造器,并传入参数,完成对象初始化,并返回。(不能调用私有的构造器)

Class c1=Cat.class;
Constructor constructor=c1.getDeclaredConstructor(String.class,int.class) ;
Cat cat=(Cat)constructor.newInstance("小橘猫",2);

4.2 setAccessible(true)

绕过私有成员的访问限制,访问/修改私有字段、方法或构造方法。

Class c1=Cat.class;
Constructor constructor=c1.getDeclaredConstructor();
constructor.setAccessible(true);
//表示禁止检查访问控制,因为Cat的无参构造方法是私有的,newInstance()
//无法访问,因此使用setAccessible(true),后续newInstance()
//才可以调用
Cat cat=(Cat)constructor.newInstance();
System.out.println(cat);

5 获取类的成员变量

5.1 getFields()

获取所有 public 字段(包括继承的)

Class c1=Cat.class;
Field[] fields=c1.getFields();
for(Field f:fields){System.out.println(f.getName()+"-->"+f.getType());
}

5.2 getDeclaredFields()

获取所有字段(包括 private,但不包括继承的)

推荐用这个

Class c1=Cat.class;
Field[] fields=c1.getDeclaredFields();
for(Field f:fields){System.out.println(f.getName()+"-->"+f.getType());
}

5. 3 getField(“参数”)

获取指定名称的 public 字段(包括继承的)

Class c1=Student .class;
Field f1=c1.getDeclaredField("name");

5.4 getDeclaredField(“参数”)

获取指定名称的字段(包括 private,但不包括继承的)

推荐用这个

Class c1=Cat.class;
Field f=c1.getDeclaredField("age");
System.out.println(f.getType());

6 使用成员变量

6.1 void set(Object obj, Object value)

修改指定对象的字段值。

Class c=Cat.class;
Field cName=c.getDeclaredField("name");
Field cAge=c.getDeclaredField("age");
Constructor constructor =c.getDeclaredConstructor();
//newInstance()无法调用私有构造器
Cat cat = (Cat) constructor.newInstance();
cName.setAccessible(true);
cName.set(cat, "加菲猫") ;
cAge.setAccessible(true) ;
cAge.set(cat, 18);

6.2 Object get(Object obj)

取变量的值

int age=(int) cAge.get(cat);

6.3 setAccessible(true)

设置为true ,表示禁止检查访问控制(暴力反射)

cAge.setAccessible(true) ;

7 获取类的成员方法

7.1 getMethods()

获得该类所有方法(只获取带有public修饰的方法)

Class dog=Dog.class;
//获取类的全部成员方法
Method[] methods=dog.getMethods();

7.2 getDeclaredMethods()

获得该类所有方法

Class dog=Dog.class;
//获取类的全部成员方法
Method[] methods=dog.getDeclaredMethods();

7.3 getDeclaredMethod(String name, Class…<?> parameterTypes)

获得该类某个方法

7.3.1 无参的
Class taidi=Dog.class;
Method eat=taidi.getDeclaredMethod("eat");//拿无参的eat方法
7.3.2 有参的
Class jing=Dog.class;
Method eat1=jing.getDeclaredMethod("eat", String.class);//拿有参的eat方法

8 执行方法

8.1 public Object invoke(Object obj, Object… args)

触发某个对象的该方法执行

8.1.1无参方法
Class taidi=Dog.class;
Method eat=taidi.getDeclaredMethod("eat");//拿无参的eat方法
System.out.println(eat.getName()+"-->"+eat.getParameterCount()+"-->"+eat.getReturnType());
//触发该无参方法
Dog dog1=new Dog();
eat.setAccessible(true);//因为无参的eat方法是private的因此设置暴力发射
Object rs=eat.invoke(dog1);//调用无参的eat方法,用dog1对象触发调用
System.out.println(rs);//返回null,因为eat无参方法的返回类型是void的
8.1.2 有参方法
//获取某个方法(有参的)
Class jing=Dog.class;
Method eat1=jing.getDeclaredMethod("eat", String.class);
System.out.println(eat1.getName()+"-->"+eat1.getParameterCount()+"-->"+eat1.getReturnType());
//调用有参的eat方法
Dog dog2=new Dog();
eat1.setAccessible(true);
String rs1=(String) eat1.invoke(dog1,"狗粮");//调用有参的eat方法,用dog2对象触发调用
System.out.println(rs1);
System.out.println("===========");

9 反射的作用,应用场景

基本作用:

  • 得到一个类的全部成分然后进行操作
  • 破坏封装性
  • 最重要的用途:适合做java框架,基本上,主流的框架都会基于反射设计出一些通用的功能

9.1 使用反射做一个简易框架

public class ObjectFrame {//目标:保存任意对象的字段和其数据到文件中去public static void saveObject(Object object) throws IllegalAccessException, FileNotFoundException {PrintStream ps = new PrintStream(new FileOutputStream("src\\data.txt", true));//obj是任意对象,到底有多少个字段可以保存Class c=object.getClass();String className=c.getSimpleName();ps.println("-----"+className+"-----");//从这个类中提取他的全部成员变量Field[] fields=c.getDeclaredFields();//遍历每个成员变量for(Field f:fields){//拿到成员变量的名字String name = f.getName();//拿到成员变量在对象中的数据f.setAccessible(true);String value= f.get(object) +"" ;ps.println(name+"="+value);}ps.close();}
}
public class TestFrame {public static void save() throws FileNotFoundException, IllegalAccessException {Student s1=new Student("张三",18,'男',178.9,"打篮球");Teacher t1=new Teacher("黎明",8000.1);ObjectFrame.saveObject(s1);ObjectFrame.saveObject(t1);}public static void main(String[] args) throws FileNotFoundException, IllegalAccessException {save();}
}
xception {Student s1=new Student("张三",18,'男',178.9,"打篮球");Teacher t1=new Teacher("黎明",8000.1);ObjectFrame.saveObject(s1);ObjectFrame.saveObject(t1);}public static void main(String[] args) throws FileNotFoundException, IllegalAccessException {save();}
}

http://www.hkcw.cn/article/gtTXrqgshT.shtml

相关文章

整数有约 | 刘乾专访:继续预训练策略与数据优化之道

人工智能多语言处理近年来得到了极大的关注&#xff0c;尤其是在以东南亚为代表的小语种环境中&#xff0c;其特殊的语言多样性和语料库稀缺性使得研究挑战和机遇并存。在现有的自然语言处理模型中&#xff0c;英语和中文因为有海量高质量数据的支持&#xff0c;常被作为核心语…

Google 发布的全新导航库:Jetpack Navigation 3

前言 多年来&#xff0c;Jetpack Navigation 库一直是开发者的重要工具&#xff0c;但随着 Android 用户界面领域的发展&#xff0c;特别是大屏设备的出现和 Jetpack Compose 的兴起&#xff0c;Navigation 的功能也需要与时俱进。 今年的 Google I/O 上重点介绍了 Jetpack Na…

抖音商城抓包 分析

声明 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 抓包展示 总结 1.出于安全考虑,本章未…

uniapp-商城-77-shop(8.2-商品列表,地址信息添加,级联选择器picker)

地址信息,在我们支付订单上有这样一个接口,就是物流方式,一个自提,我们就显示商家地址。一个是外送,就是用户自己填写的地址。 这里先说说用户的地址添加。需要使用到的一些方式方法,主要有关于地址选择器,就是uni-data-picker级联选择。 该文介绍了电商应用中地址信息处…

AlmaLinux OS 10 正式发布:兼容 RHEL 10 带来多项技术革新

AlmaLinux OS 基金会日前宣布推出 AlmaLinux OS 10&#xff0c;该版本代号代号紫色的狮子 (Purple Lion)&#xff0c;新版本带来多项新功能和技术更新&#xff0c;旨在为用户提供更强大的企业级 Linux 体验。 该系统使用与 RHEL 10 相同的源代码构建并于 RHEL 10 保持完全兼…

深入理解C# MVVM模式:从理论到实践

在现代软件开发中&#xff0c;良好的架构设计对于构建可维护、可测试和可扩展的应用程序至关重要。Model-View-ViewModel (MVVM) 是一种特别适合XAML-based应用程序&#xff08;如WPF、Xamarin和UWP&#xff09;的架构模式。本文将全面探讨MVVM模式的概念、实现细节、最佳实践以…

Git GitHub Gitee

一、Git 是一个免费、开源的分布式版本控制系统。 版本控制&#xff1a;一种记录文件内容变化&#xff0c;以便将来查阅特定版本修订情况的系统。它最重要的就是可以记录文件修改历史记录&#xff0c;从而让用户可以看历史版本&#xff0c;方便版本切换。 1.和集中式版本控制…

数据库管理-第332期 大数据已死,那什么当立?(20250602)

数据库管理332期 2025-06-02 数据库管理-第332期 大数据已死&#xff0c;那什么当立&#xff1f;&#xff08;20250602&#xff09;1 概念还是技术2 必然的大数据量3 离线到实时4 未来总结 数据库管理-第332期 大数据已死&#xff0c;那什么当立&#xff1f;&#xff08;202506…

Java Netty 中处理粘包和半包问题的解决方案 | TCP消息完整性校验(XOR )

文章目录 引言I 处理TCP粘包和半包问题背景粘包问题的产生原因解决方案WebSocket中的粘包和半包问题及解决方案II Java Netty 中处理粘包和半包问题粘包和半包问题可以通过以下几种方式解决:使用分隔符解码器基于长度字段的解码器实现自定义解码器III TCP常见封装处理消息接收…

鸿蒙next系统以后会取代安卓吗?

点击上方关注 “终端研发部” 设为“星标”&#xff0c;和你一起掌握更多数据库知识 官方可没说过取代谁谁&#xff0c;三足鼎立不好吗&#xff1f;三分天下&#xff0c;并立共存。 鸿蒙基于Linux&#xff0c;有人说套壳&#xff1b;ios/macos基于Unix&#xff0c;说它ios开源了…

排便不是一件可以随意“延后”的事:长期便秘->直肠敏感性降低->功能性便秘->大便失禁

文章目录 引言知识扩展: 快乐排便的黄金姿势I 便秘并不是一种单一成因的疾病便秘成因临床治疗II 总是压抑排便,身体会发生的变化III 排便不是一件可以随意“延后”的事引言 排便是一种复杂的反射行为: 由“直肠充盈—产生便意—括约肌协调—排出”的完整生理链条完成的。 …

基于Spring Boot 电商书城平台系统设计与实现(源码+文档+部署讲解)

技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论文…

Golang——5、函数详解、time包及日期函数

函数详解、time包及日期函数 1、函数1.1、函数定义1.2、函数参数1.3、函数返回值1.4、函数类型与变量1.5、函数作参数和返回值1.6、匿名函数、函数递归和闭包1.7、defer语句1.8、panic和recover 2、time包以及日期函数2.1、time.Now()获取当前时间2.2、Format方法格式化输出日期…

HTTP详解

使用的工具&#xff1a;fiddler 一、请求和响应报文的结构 1.请求 ⾸⾏: [⽅法] [url] [版本]Header: 请求的属性, 冒号分割的键值对;每组属性之间使⽤\n分隔;遇到空⾏表⽰Header部分结束Body: 空⾏后⾯的内容都是Body. Body允许为空字符串. 如果Body存在, 则在Header中会有…

解决:install via Git URL失败的问题

为解决install via Git URL失败的问题&#xff0c;修改安全等级security_level的config.ini文件&#xff0c;路径如下&#xff1a; 还要重启&#xff1a; 1.reset 2.F5刷新页面 3.关机服务器&#xff0c;再开机&#xff08;你也可以省略&#xff0c;试试&#xff09; 4.Wind…

【小工具开发】通过Java实现批量修改文件名小工具

1. 创建Project&#xff08;使用Gradle&#xff09; 2.安装Gradle 修改 distributionUrlhttps\://mirrors.cloud.tencent.com/gradle/gradle-8.12-bin.zip 修改 distributionUrlhttps\://mirrors.cloud.tencent.com/gradle/gradle-8.12-all.zip 阅读了以下博客&#xff0c;发…

【AI智能体】Spring AI MCP 从使用到操作实战详解

目录 一、前言 二、MCP 介绍 2.1 什么是MCP 2.2 MCP 核心特点 2.3 MCP 核心价值 2.4 MCP 与Function Calling 区别 三、Spring AI MCP 架构介绍 3.1 整体架构 3.1.1 三层架构实现说明 3.2 服务端与客户端 3.2.1 MCP 服务端 3.2.1 MCP 客户端 3.3 MCP中SSE和STDIO区…

Python打卡DAY43

复习日 作业&#xff1a; kaggle找到一个图像数据集&#xff0c;用cnn网络进行训练并且用grad-cam做可视化 进阶&#xff1a;并拆分成多个文件 我选择ouIntel Image Classification | Kagglezz&#xff0c;该数据集分为六类&#xff0c;包含建筑、森林、冰川、山脉、海洋和街道…

香橙派3B学习笔记5:Linux文件系统分区_A/B系统分区

经过之前的多次分区失败导致系统重启无法进入&#xff0c;这次调整思路重新分区 ssh &#xff1a; orangepi本地ip 密码 &#xff1a; orangepi 操作系统发行版&#xff1a; 基于 Ubuntu 20.04.6 LTS&#xff08;Focal Fossa&#xff09;的定制版本&#xff0c;专门为 Orange …

第16讲、Odoo 18 序号(Sequence)详解

目录 序号系统概述底层实现原理常见序号规则使用方法与最佳实践案例分析&#xff1a;客户工单管理系统常见问题与解决方案总结 序号系统概述 Odoo 中的序号&#xff08;Sequence&#xff09;系统是一个用于生成唯一标识符的核心机制&#xff0c;主要用于为业务单据&#xff…