(JAVA)-反射

什么是反射?

反射允许对成员变量,成员方法和构造方法的信息进行编程访问。

说简单点就是反射能将类里面的构造方法,成员变量,修饰符,返回值,注解,类型,甚至异常等类里面的所有东西都能够获取出来。

关于Class的介绍:Class类是用来描述类的类,它是一个十分特殊的类,没有构造方法。Class对象的加载过程如下:当程序运行时,我们编写的每一个类都会被编译生成 类名.class 文件,当我们我们new对象或者类加载器加载的时候,JVM就会加载我们的 类名.class 文件并且加载到内存中,即当一个类加载完成之后,在堆内存的方法区中就生成了一个该类唯一的Class对象(一个类只会对应一个Class对象,绝对不会产生第二个),这个Class对象就包含了完整的类的结构信息,用于表示该类的所有信息。

但是我们获取不是从java文件中获取的,而是从class字节码文件中获取的,所以我们先来讲一讲如何获取字节码文件对象。

一:反射获取类对象

java代码运行可以分为以下几个阶段:

1.源代码阶段:编写java文件,然后把他编译成字节码文件。没有把代码加载到内存当中,只是在硬盘进行操作。

2.加载阶段:把字节码文件加载到内存当中

3.运行阶段:在内存当中获取对象

以下三种获取对象的方式分别对应着上面三个阶段获取:

1.Class.forNmae("全类名");      2.类名.class;      3.对象.getClass;

这里所有举例都用student类来作为演示,所以先创建一个student类,后面会一直用这个。

package H;
//创建学生类
public class student {private String name;private int age;public student() {}public student(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "student{" +"name='" + name + '\'' +", age=" + age +'}';}
}

 获取类对象的三种方法

 public static void main(String[] args) throws ClassNotFoundException {Class aClass = Class.forName("H.student");Class bClass =student.class;//最为常用student s=new student();//当作参数进行传递Class cclass=s.getClass();//已经有了这个类的对象才可以使用}
}

二:反射获取构造方法

Constructor就是java中构造方法的类

 演示以下:

public class test {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {Class aClass = Class.forName("H.student");//最为常用Class bClass =student.class;//当作参数进行传递student s=new student();Class cclass=s.getClass();//已经有了这个类的对象才可以使用Constructor[] constructors1 = aClass.getConstructors();//获取全部公共构造方法Constructor[] constructors2 = aClass.getDeclaredConstructors();//获取全部构造方法Constructor constructor1 = aClass.getConstructor(String.class,int.class);//获取参数传递的类型的构造方法Constructor constructor2 = aClass.getDeclaredConstructor();//}
}

获取到Constructor对象可以调用Constructor类中的getModifiers方法获取他的权限修饰符。

打印出来的结果是整形形式,代表不同的权限修饰符。

int modifiers=constructor1.getModifiers();

用获取到的构造方法创建对象:

1.形参需要跟构造对象一致。

2.当构造是私有方法时,不能直接创建对象,需要使用setAccssible方法临时取消权限校验(暴力反射)。

sonstructor1.setAccessible(ture);
student stu=(student) constructor1.newInstance("张三",23);

三:反射获取成员变量

field就是java中成员变量的类

  Field field = aClass.getField("name");

获取成员变量的权限修饰符:打印出来的结果是整形形式,代表不同的权限修饰符。

int modifiers=field.getModifiers();

获取成员的成员变量名:

String n=field.getType();

 获取成员的数据类型:

Class<?> type=name.getTypt();

获取成员变量记录的值:

当成员是私有时,需要使用setAccssible方法临时取消权限校验(暴力反射),来查看对象的值

student s=new student("张三","23");
name.setAccessible(true);
Object values=name.get(s);

修改对象里记录的成员变量的值:

当成员是私有时,需要使用setAccssible方法临时取消权限校验(暴力反射),来修改对象的值

name.set(a,"诩子");

四:反射获取成员方法:

Method类就是java类中的成员方法的类

1.获取成员方法

 Method[] methods = aClass.getMethods();for (Method method : methods) {System.out.println(method);}method m=class.getMethod("eat",String.class);

注意:getMethod方法包括从父类继承的方法。

获取方法的名字:

String name=m.getName();

获取方法的形参:

int num =m.getParameterCount();//获取形参个数
Class<>[] p=m.getParameterTypes();//获取形参类型
Paramemter[] parameters=m.getParameters();//获取方法的形参

获取方法抛出的异常:

Class<?>[] exceptionTypes=m.getExceptionTypes();

运行方法:当成员是私有时,需要使用setAccssible方法临时取消权限校验(暴力反射),来修改对象的值

object invoke(Object obj,object... args)
//参数一:方法调用者,用obj对象调用该方法
//参数二:方法的形参
//参数三:方法的返回值,当没有返回值就不写
students s=new students();
m.invoke(s,"汉堡包");

 细节:我们发现当操作到私有化的参数且是跟实际对象有关的操作(查看对象数值,修改对象数值),需要使用暴力反射。

反射的作用:

1.获取一个类里面的所有的信息,获取到了之后,再执行其他的业务逻辑

2.结合配置文件,动态的创建对象并调用方法。

我们通过两个小练习来体现:

test1:保存对象所有的字段名和值到文件中

public class test {public static void main(String[] args) throws IllegalAccessException, IOException {student s=new student("诩",18,'女',168,"熬夜");teacher t=new teacher("俊",10000);saveObject(s);}public static void saveObject(Object obj) throws IllegalAccessException, IOException {BufferedWriter bw=new BufferedWriter(new FileWriter("D:\\code\\javaee\\myFrect\\src\\test"));Class aClass = obj.getClass();Field[] fidles = aClass.getDeclaredFields();for (Field fidle : fidles) {fidle.setAccessible(true);String name=fidle.getName();Object value = fidle.get(obj);bw.write(name+"="+value);bw.newLine();}bw.close();}
}

test2:通过配置文件动态创建对象

  public static void main(String[] args) throws IOException {Properties prop =new Properties();prop.put("className","D:\\code\\javaee\\myFrect\\src\\H2\\student.java");prop.put("methodName","study");FileOutputStream fos = new FileOutputStream("D:\\code\\javaee\\myFrect\\src\\prop.properties");prop.store(fos,"无");fos.close();Properties prop1 =new Properties();FileInputStream fis=new FileInputStream("D:\\code\\javaee\\myFrect\\src\\prop.properties");prop1.load(fis);String className=(String)prop1.get("className");String methodName=(String)prop1.get("methodName");System.out.println(className);System.out.println(methodName);fis.close();}

注意:配置文件是一个特殊的双列集合,里面有方法能跟IO结合。

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

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

相关文章

团子杂记:SAP PS or 项目管理软件(PMIS )? PPM/P6

众所周知SAP的PS模块在项目型企业的SAP应用中扮演着核心角色&#xff0c;整个项目端到端的业务执行、财务核算、控制及分析都是通过PS作为主线&#xff0c;依赖于PS中的项目对象&#xff08;如WBS元素、网络活动等&#xff09;实现的。 在实施SAP的过程中&#xff0c;可以看到…

Nest 框架:解锁企业级 Web 应用开发的秘密武器(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

RKE安装k8s及部署高可用rancher之证书私有证书但是内置的ssl不放到外置的LB中 4层负载均衡

先决条件# Kubernetes 集群 参考RKE安装k8s及部署高可用rancher之证书在外面的LB&#xff08;nginx中&#xff09;-CSDN博客CLI 工具Ingress Controller&#xff08;仅适用于托管 Kubernetes&#xff09; 创建集群k8s [rootnginx locale]# cat rancher-cluster.yml nodes:- …

网络安全—模拟ARP欺骗

文章目录 网络拓扑安装使用编辑数据包客户机攻击机验证 仅做实验用途&#xff0c;禁止做违法犯罪的事情&#xff0c;后果自负。当然现在的计算机多无法被欺骗了&#xff0c;开了防火墙ARP欺骗根本无效。 网络拓扑 均使用Windows Server 2003系统 相关配置可以点击观看这篇文章…

【iOS安全】JS 调用Objective-C中WKWebview Handler的三种方式

有三种实现途径 1. WKScriptMessageHandler OC部分&#xff1a;注册并实现Handler 将OC中的方法"nativeMethod"注册为JavaScript Message Handler&#xff0c;从而WebView中的JavaScript代码可以调用该方法 // Register in Objective-C code - (void)setupWKWebVi…

算法通关村番外篇-数组实现队列

大家好我是苏麟 , 今天来用数组实现一下队列 . 数组实现队列 顺序存储结构存储的队列称为顺序队列&#xff0c;内部使用一个一维数组存储&#xff0c;用一个队头指针 front 指向队列头部节点(即使用int类型front来表示队头元素的下标)&#xff0c;用一个队尾指针rear(有的地方…

vue3中pdf打印问题处理

1 get请求参数问题 之前的请求是post得不到参数&#xff0c;今天发现的问题很奇怪&#xff0c;从前端进入网关&#xff0c;网关居然得不到参数。 前端代码 const print () > {let linkUrlStr proxy.$tool.getUrlStr(proxy.$api.invOrder.psiInvOrder.printSalOutstock,{a…

【Java】面向对象程序设计 期末复习总结

语法基础 数组自带长度属性 length&#xff0c;可以在遍历的时候使用&#xff1a; int []ages new int[10];for (int i 0; i < ages.length; i)System.out.println(ages[i]); 数组可以使用增强式for语句进行只读式遍历&#xff1a; int[] years new int[10];for (int ye…

Git(3):Git环境常用命令

1 获取本地仓库 要使用Git对我们的代码进行版本控制&#xff0c;首先需要获得本地仓库 &#xff08;1&#xff09;在电脑的任意位置创建一个空目录&#xff08;例如test&#xff09;作为我们的本地Git仓库 &#xff08;2&#xff09;进入这个目录中&#xff0c;点击右键打开…

ElasticSearch数据同步

文章目录 ElasticSearch数据同步1. 同步调用2. 异步通知3. 监听binlog4. 工作中处理同步的问题 ElasticSearch数据同步 ElasticSearch中酒店数据来自于mysql数据库&#xff0c;因此MySQL数据发生改变时&#xff0c;ElasticSearch也必须跟着改变&#xff0c;这个就是ElasticSear…

一个基于SpringBoot+Thymeleaf渲染的图书管理系统

功能: 用户: a.预约图书 b.查看预约记录 c.还书 管理员: a.添加图书 b.处理预约(借书) c.查看借阅记录 另: 1.当用户过了还书日期仍旧未还书时会发邮件通知 2.当有书被还时发邮件通知预约书的用户到图书馆进行借书

八大算法排序@冒泡排序(C语言版本)

冒泡排序 概念 冒泡排序&#xff08;Bubble Sort&#xff09;是一种简单直观的排序算法&#xff0c;它重复地遍历待排序序列&#xff0c;一次比较两个相邻的元素&#xff0c;如果它们的顺序错误就将它们交换过来。通过多次的遍历&#xff0c;使得最大的元素逐渐移动到待排序序…

【人工智能】百度智能云千帆AppBuilder,快速构建您的专属AI原生应用

大家好&#xff0c;我是全栈小5&#xff0c;欢迎来到《小5讲堂》&#xff0c;此序列是《人工智能》专栏文章。 这是2024年第5篇文章&#xff0c;此篇文章是进行人工智能相关的实践序列文章&#xff0c;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&…

docker小白第十一天

docker小白第十一天 dockerfile分析 Dockerfile是用来构建Docker镜像的文本文件&#xff0c;是由一条条构建镜像所需的指令和参数构成的脚本。即构建新镜像时会用到。 构建三步骤&#xff1a;编写dockerfile文件-docker build命令构建镜像-docker run镜像 运行容器实例。即一…

气缸功能块(SMART PLC梯形图代码)

有关气缸功能块的更多介绍,可以参考下面链接文章: https://rxxw-control.blog.csdn.net/article/details/125459568https://rxxw-control.blog.csdn.net/article/details/125459568CODESYS平台双通气缸功能块 https://rxxw-control.blog.csdn.net/article/details/12544822…

Linux 进程(七) 进程地址空间

虚拟地址/线性地址 学习c语言的时候我们经常会用到 “&” 符号&#xff0c;以及下面这张表&#xff0c;那么取出来的地址是否对应的是真实的物理地址呢&#xff1f;下面我们来写代码一步一步的验证。 从上面这张图不难看出&#xff0c;从正文代码&#xff0c;到命令行参数环…

Django Web 开发实战-实现用户管理系统(部门管理、用户管理、注册登录、文件上传)

简介 基于Django Python Web框架 MySQL Bootstrap 开发的用户管理系统。支持增删改查、模糊搜索、分页。 功能介绍 部门管理---》已完成 用户管理---》已完成 认证&#xff08;注册/登录&#xff09;---》开发中 数据统计---》待开发 文件上传---》待开发 效果图 部门…

Rust圣经 阅读 数值类型

基本类型 Rust 每个值都有其确切的数据类型&#xff0c;分为两类&#xff1a;基本类型和复合类型。 基本类型往往是一个最小化原子类型&#xff0c;无法解构为其它类型&#xff08;一般意义上来说&#xff09;&#xff0c;由以下组成&#xff1a; 数值类型&#xff1a;有符号…

印象笔记03 衍生软件使用

印象笔记03 衍生软件使用 Verse 以下内容来源于官方介绍 VERSE是一款面向未来的智能化生产力工具&#xff0c;由印象笔记团队诚意推出。 你可以用VERSE&#xff1a; 管理数字内容&#xff0c;让信息有序高效运转&#xff1b;搭建知识体系&#xff0c;构建你的强大知识库&am…

CMU15-445-Spring-2023-Project #0 - C++ Primer

前置任务。 Task #1 - Copy-On-Write Trie Copy-on-write (COW) Trie 在进行修改时&#xff0c;不会立即复制整个数据结构。相反&#xff0c;它会在需要修改的节点被多个引用的时候才进行复制。当要对某个节点进行写操作&#xff08;添加子节点或者继续向下insert&#xff09…