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

Java-反射

反射概述

Java反射机制:

  • 是指在运行时去获取一个类的变量和方法信息。
  • 然后通过获取的信息来创建对象,调用方法的一种机制。
  • 由于这种<动态性>,可以极大的增强程序的灵活性,程序不用在编译期就完成确定,在运行期仍然可以扩展。

获取Class类的对象

在这里插入图片描述

案例:

//Student类
public class Student {/*** 成员变量:私有,默认,公共*/private String name;int age;public String address;//构造方法:一个私有,一个默认,两个公共public Student() {}private Student(String name) {this.name = name;}Student(String name, int age) {this.name = name;this.age = age;}public Student(String name, int age, String address) {this.name = name;this.age = age;this.address = address;}/*** 成员方法:一个私有,四个公共*/private void function() {System.out.println("function");}public void method1() {System.out.println("method");}public void method2(String s) {System.out.println("method:" + s);}public String method3(String s, int i) {return s + "," + i;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", address='" + address + '\'' +'}';}
}
public class Demo {public static void main(String[] args) throws ClassNotFoundException {//使用类的class属性获取该类对应的Class对象Class<Student> c1 = Student.class;System.out.println(c1);//一个类在内存中只有一个字节码文件对象Class<Student> c2 = Student.class;System.out.println(c1 == c2);System.out.println("-------------------");/*通过调用对象的getClass()方法,返回对象所属类的class对象该方法是Object类中的方法,所有的Java对象都可以调用该方法*/Student stu = new Student();Class<? extends Student> c3 = stu.getClass();System.out.println(c1 == c3);System.out.println("-------------------");//使用Class类中的静态方法forName(String className),返回对象所属类的class对象Class<?> c4 = Class.forName("com.fanshe.Student");System.out.println(c1 == c4);}
}

运行结果:

class com.fanshe.Student
true
-------------------
true
-------------------
true

反射获取构造方法并使用

  • getConstructors():返回一个数组,包含该Class对象中的public公共构造函数
  • getDeclaredConstructors():返回一个数组,包含该Class对象中的所有构造函数
  • getConstructor(参数列表):获取指定的公共构造函数对象
  • getDeclaredConstructor(参数列表):获取指定的构造函数对象
  • newInstance(参数):构造方法创建对象
  • setAccessible(boolean flag):值为true时取消访问检查

练习:

public class Demo2 {public static void main(String[] args) throws Exception {//获取Class对象Class<?> c = Class.forName("com.fanshe.Student");//getConstructors():返回一个数组,包含该Class对象中的public公共构造函数Constructor<?>[] cons = c.getConstructors();System.out.println("公共构造函数:");for (Constructor<?> con : cons) {System.out.println(con);}//getDeclaredConstructors():返回一个数组,包含该Class对象中的所有构造函数Constructor<?>[] dCons = c.getDeclaredConstructors();System.out.println("所有构造函数:");for (Constructor<?> dCon : dCons) {System.out.println(dCon);}System.out.println("指定的公共构造函数1:");//getConstructor():返回指定的公共构造函数的对象//参数:构造方法的参数 和 数据类型对应的字节码文件对象(Class对象)Constructor<?> con = c.getConstructor();//公共构造函数的对象使用newInstance()创建实例对象//newInstance():构造方法创建对象Object obj = con.newInstance();System.out.println(obj);System.out.println("指定的公共构造函数2:");//基本数据类型 也可以通过.class 得到对应的Class类型System.out.println(c.getConstructor(String.class, int.class, String.class).newInstance("李白",22,"西安"));System.out.println("指定的构造函数");//getDeclaredConstructor():获取指定的构造函数//参数:构造方法的参数 和 数据类型对应的字节码文件对象(Class对象)Constructor<?> dCon = c.getDeclaredConstructor(String.class);//setAccessible():值为true时取消访问检查dCon.setAccessible(true);System.out.println(dCon.newInstance("杨玉环"));}
}

运行结果:

公共构造函数:
public com.fanshe.Student(java.lang.String,int,java.lang.String)
public com.fanshe.Student()
所有构造函数:
public com.fanshe.Student(java.lang.String,int,java.lang.String)
com.fanshe.Student(java.lang.String,int)
private com.fanshe.Student(java.lang.String)
public com.fanshe.Student()
指定的公共构造函数1Student{name='null', age=0, address='null'}
指定的公共构造函数2Student{name='李白', age=22, address='西安'}
指定的构造函数
Student{name='杨玉环', age=0, address='null'}

反射获取成员变量并使用

Class类中用于获取成员变量的方法

  • getFields():获取公共的成员变量
  • getDeclaredFields():获取所有的成员变量
  • getField(成员变量):获取指定的公共成员变量
  • getDeclaredField(成员变量):获取指定的成员变量

Field类中,给成员变量赋值的方法

  • set(Object obj,Object value):给obj方法实例中的成员变量赋值

练习:

public class Demo3 {public static void main(String[] args) throws Exception {//获取Class对象Class<?> c = Class.forName("com.fanshe.Student");//getFields():获取公共的成员变量Field[] fields = c.getFields();System.out.println("获取公共的成员变量:");for (Field field : fields) {System.out.println(field);}//getDeclaredFields():获取所有的成员变量Field[] df = c.getDeclaredFields();System.out.println("获取所有的成员变量:");for (Field field : df) {System.out.println(field);}System.out.println("获取指定的公共成员变量并赋值,再创建对象:");//获取指定的公共成员变量Field addressField = c.getField("address");//获取指定的公共构造方法,并创建方法实例Object obj = c.getConstructor().newInstance();//给方法中的成员变量赋值addressField.set(obj,"西安");//输出方法实例(对象)System.out.println(obj);System.out.println("获取指定的公共构造函数对象,再实例化对象:");//获取单个公共方法Constructor<?> con = c.getConstructor();//创建方法实例Object obj1 = con.newInstance();System.out.println(obj1);System.out.println("获取指定的成员变量并赋值,再实例化对象:");//获取指定的成员变量Field nameField = c.getDeclaredField("name");Field ageField = c.getDeclaredField("age");Field addField = c.getDeclaredField("address");//取消访问检查nameField.setAccessible(true);ageField.setAccessible(true);addField.setAccessible(true);//给成员变量赋值nameField.set(obj1,"胡辣汤");ageField.set(obj1,10);addField.set(obj1,"北京");//输出对象System.out.println(obj1);}
}

运行结果:

获取公共的成员变量:
public java.lang.String com.fanshe.Student.address
获取所有的成员变量:
private java.lang.String com.fanshe.Student.name
int com.fanshe.Student.age
public java.lang.String com.fanshe.Student.address
获取指定的公共成员变量并赋值,再创建对象:
Student{name='null', age=0, address='西安'}
获取指定的公共构造函数对象,再实例化对象:
Student{name='null', age=0, address='null'}
获取指定的成员变量并赋值,再实例化对象:
Student{name='胡辣汤', age=10, address='北京'}

反射获取成员方法并使用

Class类中用于获取成员方法的方法

  • getMethods():获取全部的公共成员方法数组,包含继承的方法
  • getDeclaredMethods():获取全部的成员方法数组,不包含继承的方法
  • getMethod(“方法名”,参数类型.class):获取单个公共成员方法对象
  • getDeclaredMethod(“方法名”,参数类型.class):获取单个成员方法对象

Method类中用于调用成员方法的方法

  • invoke(实体类对象,方法参数列表):调用实体类对象的成员方法

练习:

public class Demo4 {public static void main(String[] args) throws Exception {//获取Class对象Class<?> c = Class.forName("com.fanshe.Student");System.out.println("获取全部的公共成员方法:");//getMethods():获取全部的公共成员方法,包含继承的方法Method[] methods = c.getMethods();for (Method method : methods) {System.out.println(method);}System.out.println("获取全部的成员方法:");//getDeclaredMethods():获取全部的成员方法,不包含继承的方法Method[] dms = c.getDeclaredMethods();for (Method dm : dms) {System.out.println(dm);}System.out.println("获取单个的公共成员方法1:");//getMethod("方法名",参数类型.class):获取单个的公共成员方法对象Method method1 = c.getMethod("method1");//获取无参构造方法,创建实体类对象Object obj1 = c.getConstructor().newInstance();//invoke(实体类对象,方法参数列表):调用对象的成员方法method1.invoke(obj1);System.out.println("获取单个的公共成员方法2:");Method method2 = c.getMethod("method2",String.class);method2.invoke(obj1,"马超");System.out.println("获取单个的公共成员方法3:");Method method3 = c.getMethod("method3", String.class, int.class);//有返回值,先接收一下Object obj2 = method3.invoke(obj1, "赵云", 22);//输出返回结果System.out.println(obj2);System.out.println("获取单个的成员方法:");//getDeclaredMethod("方法名",参数类型):获取单个的成员方法对象Method dm = c.getDeclaredMethod("function");//取消访问检查dm.setAccessible(true);dm.invoke(obj1);}
}

运行结果:

获取全部的公共成员方法:
public java.lang.String com.fanshe.Student.toString()
public void com.fanshe.Student.method1()
public java.lang.String com.fanshe.Student.method3(java.lang.String,int)
public void com.fanshe.Student.method2(java.lang.String)
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
获取全部的成员方法:
public java.lang.String com.fanshe.Student.toString()
private void com.fanshe.Student.function()
public void com.fanshe.Student.method1()
public java.lang.String com.fanshe.Student.method3(java.lang.String,int)
public void com.fanshe.Student.method2(java.lang.String)
获取单个的公共成员方法1:
method
获取单个的公共成员方法2:
method:马超
获取单个的公共成员方法3:
赵云,22
获取单个的成员方法:
function

反射练习-越过泛型检查

如何实现在ArrayList< Integer >集合中添加一个字符串数据?

public class Demo5 {public static void main(String[] args) throws Exception {//创建集合ArrayList<Integer> list = new ArrayList<>();//添加数据list.add(10);list.add(20);list.add(30);//输出集合System.out.println(list);//利用反射,在list中添加一个String数据Class<? extends ArrayList> lc = list.getClass();Method ad = lc.getMethod("add", Object.class);ad.invoke(list,"hello");//输出添加String数据后的集合System.out.println(list);}
}

运行结果:

[10, 20, 30]
[10, 20, 30, hello]

反射练习-运行配置文件指定内容

通过配置文件运行类中的方法

//老师类
public class Teacher {public void teach(){System.out.println("为师教你做人");}
}
//学生类
public class Student1 {public void study(){System.out.println("学生喜读春秋");}
}
#配置文件
className=com.fanshe.Teacher
methodName=teach
//测试类
public class Demo6 {public static void main(String[] args) throws Exception {//学生Student1 stu = new Student1();stu.study();//老师Teacher tea = new Teacher();tea.teach();System.out.println("-----配置文件实现操作-----------");//加载数据Properties pro = new Properties();FileReader fr = new FileReader("idea_test\\class.txt");pro.load(fr);fr.close();//获取配置文件中的内容String className = pro.getProperty("className");String methodName = pro.getProperty("methodName");//通过反射来使用Class<?> c = Class.forName(className);//根据无参构造方法,创建实体类对象Object obj = c.getConstructor().newInstance();//获取单个成员方法Method dm = c.getDeclaredMethod(methodName);//取消访问权限dm.setAccessible(true);//调用方法dm.invoke(obj);}
}

运行结果:

学生喜读春秋
为师教你做人
-----配置文件实现操作-----------
为师教你做人

相关文章:

Java-反射

反射概述 Java反射机制&#xff1a; 是指在运行时去获取一个类的变量和方法信息。然后通过获取的信息来创建对象&#xff0c;调用方法的一种机制。由于这种<动态性>&#xff0c;可以极大的增强程序的灵活性&#xff0c;程序不用在编译期就完成确定&#xff0c;在运行期仍…...

构造agent类型的内存马(内存马系列篇十三)

写在前面 前面我们对JAVA中的Agent技术进行了简单的学习&#xff0c;学习前面的Agent技术是为了给这篇Agent内存马的实现做出铺垫&#xff0c;接下来我们就来看看Agent内存马的实现。 这是内存马系列篇的第十三篇了。 环境搭建 我这里就使用Springboot来搭建一个简单的漏洞…...

JavaEE简单示例——<select>中的查询参数传递和结果集封装自动映射关系

简单介绍&#xff1a; 在之前我们在讲SQL映射文件中的映射查询语句的<select>标签的时候&#xff0c;对其中的四个常用属性的讲解并不是那么的透彻&#xff0c;今天就来详细的解释<select>的四个常用属性的具体含义以及<select>标签在进行查询的时候查询参数…...

信息安全圈都在谈论CISP,CISSP,这两者有什么区别呢?

CISP 和 CISSP 都是信息安全认证资格考试&#xff0c;但是它们之间有一些区别。 CISP&#xff08;Certified Information Security Professional&#xff09;认证考试是由国际信息系统安全认证联盟&#xff08;ISC)所开发和管理的&#xff0c;主要考核信息安全专业人员在保障企…...

浅谈Redisson实现分布式锁的原理

1.Redisson简介 Redis 是最流行的 NoSQL 数据库解决方案之一&#xff0c;而 Java 是世界上最流行&#xff08;注意&#xff0c;我没有说“最好”&#xff09;的编程语言之一。虽然两者看起来很自然地在一起“工作”&#xff0c;但是要知道&#xff0c;Redis 其实并没有对 Java…...

UVM实战(张强)-- UVM中的寄存器模型

目录一.整体的设计结构图二.各个组件代码详解2.1 DUT2.2 bus_driver2.3 bus_sequencer2.4 bus_monitor2.5 bus_agent2.6 bus_transaction2.7 bus_if2.8 my_if2.9 my_transaction2.10 my_sequencer2.11 my_driver2.12 my_monitor2.13 my_agent2.14 my_scoreboard2.15 my_env2.16…...

什么是 CSAT?这份客户满意度流程指南请查收

什么是 CSAT&#xff1f;如何计算我的客户满意度分数&#xff1f;大中型公司应该熟悉这些术语。以下文章旨在教您有关客户满意度流程的所有内容 - 基本的CSAT概念、创建CSAT调查的好处、如何创建CSAT调查。配图来源&#xff1a; SaleSmartly(ss客服) 一、什么是 CSAT&#xff1…...

AD域备份和恢复工具

Microsoft的本地Active Directory备份和恢复功能不适用于对象级备份和属性级还原。使用RecoveryManager Plus&#xff0c;您不仅可以备份和还原所有AD对象&#xff0c;还可以备份和还原其他基本AD元素&#xff0c;例如架构属性&#xff0c;组成员身份信息和Exchange属性。此外&…...

老学长的浙大MPA现场复试经验分享

作为一名在浙大MPA项目已经毕业的考生来说&#xff0c;很荣幸受到杭州达立易考周老师的邀请&#xff0c;给大家分享下我的复试经验&#xff0c;因为听周老师说是这几年浙大MPA因疫情情况&#xff0c;已经连续几年都是线上个人复试了&#xff0c;而今年疫情社会面较为平稳的情况…...

制作证书链并进行验证

生成自签名的根证书: openssl req -x509 -newkey rsa -outform PEM -out tls-rootca.pem -keyform PEM -keyout tls-rootca.key.pem -days 35600 -nodes -subj “/C=cn/O=mycomp/OU=mygroup/CN=rootca” 生成中间证书 1.生成csr和key文件 openssl req -newkey rsa:2048 -outf…...

基于python多光谱遥感数据处理、图像分类、定量评估及机器学习方法应用

基于卫星或无人机平台的多光谱数据在地质、土壤调查和农业等应用领域发挥了重要作用&#xff0c;在地质应用方面&#xff0c;综合Aster的短波红外波段、landsat热红外波段等多光谱数据&#xff0c;可以通过不同的多光谱数据组合&#xff0c;协同用于矿物信息有效提取。此外&…...

初识 git--本地仓库

目录&#xff1a;一&#xff0c;基础步骤&#xff1a;1&#xff0c;安装2&#xff0c;配置3&#xff0c;检查配置4&#xff0c;创建仓库 - repository5&#xff0c;查看工作区的文件状态6&#xff0c;如果显示乱码的解决方式git status 显示乱码终端乱码7&#xff0c;添加工作区…...

Redis学习之持久化(六)

这里写目录标题一、持久化简介1.1 持久化1.2 Redis持久化的两种形式二、RDB2.1 RDB概念2.2 save指令手动执行一次保存配置相关参数2.3 bgsave指令2.4 save配置自动执行2.5 RDB三种启动方式对比三、AOF3.1 AOF概念3.2 AOF执行策略3.3 AOF重写四、RDB和AOF区别2.1 RDB与AOF对比&a…...

C++11 之 auto decltype

文章目录autodecltypesauto 和 decltype 的配合—返回值类型后置关于 c11 新特性&#xff0c;最先提到的肯定是类型推导&#xff0c;c11 引入了 auto 和 decltype 关键字&#xff0c;使用他们可以在编译期就推导出变量或者表达式的类型&#xff0c;方便开发者编码也简化了代码。…...

论文笔记:How transferable are features in deep neural networks? 2014年NIP文章

文章目录一、背景介绍二、方法介绍三、实验论证四、结论五、感想参考文献一、背景介绍 1.问题介绍&#xff1a; 许多在自然图像上训练的深度神经网络都表现出一个奇怪的共同现象&#xff1a;在第一层&#xff0c;它们学习类似于Gabor过滤器和color blobs的特征。这样的第一层特…...

python基于flask共享单车系统vue

可定制框架:ssm/Springboot/vue/python/PHP/小程序/安卓均可开发 目录 1 绪论 1 1.1课题背景 1 1.2课题研究现状 1 1.3初步设计方法与实施方案 2 1.4本文研究内容 2 2 系统开发环境 4 2. 3 系统分析 6 3.1系统可行性分析 6 3.1.1经济可行性 6 3.1.2技术可行性 6 3.1.3运行可行…...

C++11 之模板改进

模板的右尖括号 在 c98/03 的泛型编程中&#xff0c;模板实例化有一个很烦琐的地方&#xff0c;那就是连续两个右尖括号&#xff08;>>&#xff09;会被编译器解释成右移操作符&#xff0c;而不是模板参数表的结束&#xff0c;所以需要中间加个空格进行分割&#xff0c;…...

Linux - POSIX信号量,基于环形队列的生产者消费者模型

信号量在Linux下&#xff0c;POSIX信号量是一种线程同步机制&#xff0c;用于控制多个线程之间的访问顺序。POSIX信号量可以用于实现线程之间的互斥或者同步。在之前的阻塞队列生产者消费者模型中&#xff0c;阻塞队列是一个共享资源&#xff0c;不管是生产者还是消费者&#x…...

学习Flask之七、大型应用架构

学习Flask之七、大型应用架构 尽管存放在单一脚本的小型网络应用很方便&#xff0c;但是这种应用不能很好的放大。随着应用变得复杂&#xff0c;维护一个大的源文件会出现问题。不像别的网络应用&#xff0c;Flask没有强制的大型项目组织结构。构建应用的方法完全留给开发者。…...

CentOS9下编译FFMPEG源码

克隆...

挑战杯推荐项目

“人工智能”创意赛 - 智能艺术创作助手&#xff1a;借助大模型技术&#xff0c;开发能根据用户输入的主题、风格等要求&#xff0c;生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用&#xff0c;帮助艺术家和创意爱好者激发创意、提高创作效率。 ​ - 个性化梦境…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持&#xff0c;都是在为未来积攒底气。 案例&#xff1a;OLED显示一个A 这边观察到一个点&#xff0c;怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 &#xff1a; 如果代码里信号切换太快&#xff08;比如 SDA 刚变&#xff0c;SCL 立刻变&#…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

AI病理诊断七剑下天山,医疗未来触手可及

一、病理诊断困局&#xff1a;刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断"&#xff0c;医生需通过显微镜观察组织切片&#xff0c;在细胞迷宫中捕捉癌变信号。某省病理质控报告显示&#xff0c;基层医院误诊率达12%-15%&#xff0c;专家会诊…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...

Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案

在大数据时代&#xff0c;海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构&#xff0c;在处理大规模数据抓取任务时展现出强大的能力。然而&#xff0c;随着业务规模的不断扩大和数据抓取需求的日益复杂&#xff0c;传统…...

如何在Windows本机安装Python并确保与Python.NET兼容

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…...

热门Chrome扩展程序存在明文传输风险,用户隐私安全受威胁

赛门铁克威胁猎手团队最新报告披露&#xff0c;数款拥有数百万活跃用户的Chrome扩展程序正在通过未加密的HTTP连接静默泄露用户敏感数据&#xff0c;严重威胁用户隐私安全。 知名扩展程序存在明文传输风险 尽管宣称提供安全浏览、数据分析或便捷界面等功能&#xff0c;但SEMR…...

Tauri2学习笔记

教程地址&#xff1a;https://www.bilibili.com/video/BV1Ca411N7mF?spm_id_from333.788.player.switch&vd_source707ec8983cc32e6e065d5496a7f79ee6 官方指引&#xff1a;https://tauri.app/zh-cn/start/ 目前Tauri2的教程视频不多&#xff0c;我按照Tauri1的教程来学习&…...

NineData数据库DevOps功能全面支持百度智能云向量数据库 VectorDB,助力企业 AI 应用高效落地

NineData 的数据库 DevOps 解决方案已完成对百度智能云向量数据库 VectorDB 的全链路适配&#xff0c;成为国内首批提供 VectorDB 原生操作能力的服务商。此次合作聚焦 AI 开发核心场景&#xff0c;通过标准化 SQL 工作台与细粒度权限管控两大能力&#xff0c;助力企业安全高效…...