【JavaSE】反射

Java代码的生命周期

Java代码在计算机中经历的阶段:Source源代码阶段、Class类对象阶段、RunTime运行时阶段。

Source源代码阶段: 这个阶段是由程序员编写生成源代码,再由Javac编译器生成class文件。

Class类对象阶段:由类加载器将class文件加载到JVM内存中,并对class文件进行解析生成Class对象。

Runtime运行时阶段:由class对象创建对应的类对象。

反射的概念

正射与反射

正射:一般情况下,我们创建对象时就知道需要创建什么类,所以直接new一个对应类型的对象。

Car car = new Car();

反射:在创建对象时,并不知道对象类型。需要一定的手段(下文中获取class对象的方式)去找到其类型,再将该类型分装成class对象,class对象根据找到的类型再去创建对应类型的对象。

分析Java代码的阶段时,ClassLoader将class文件加载到内存,并且创建class对象,将原本class文件的各个部分都封装成对象。后面在运行时通过class对象及其内部的其他对象去生成最后程序真正所需要的对象。这个过程就是反射。

总结

正射是先创建对象,再访问类信息。

反射是获取信息,再创建对象。

反射的优点

1.可以在程序运行的过程中,动态的获取类信息,并进行操作。比较灵活。

比如Idea的提示功能,Idea之所以能够提示类中的各种信息,就是通过反射获取到了类信息。

2.可实现解耦,增强程序的可扩展性。

通过反射机制,可以动态的获取类信息,并进行操作。在庞大的项目中,面对复杂的需求,利用反射机制可以做到不修改源代码的情况下,就可以实现不同的功能。

比如启动Tomcat服务器时,用户修改了配置文件中的端口号,那么服务器就可以使用用户指定的端口号。这就是将配置文件与Tomcat程序进行解耦。

反射的使用过程

1.查找类信息。

类信息可以是字节码文件、加载到内存中的类信息(解析了字节码文件之后的信息)、对象(对象中包含着类的详细信息)。

2.根据类信息创建Class对象。

3.通过Class对象动态的获取类信息,甚至操作类信息。

Class对象的获取方式

使用反射的核心就是获取到Class对象。Java是面向对象的编程语言,反射根据类信息创建Class对象,而想要动态的将类信息获取出来就属于Class对象的职能了。

1.Class.forName(String className)

这种方式是通过Class类获取的。

这种方式是在Source源代码阶段,根据className找到对应的class文件,在文件中获取到类信息,将其信息的各个组成部分封装成对象。

类的各个组成部分:成员变量、成员方法、构造器、静态资源等。

使用场景:多用于读取配置文件来加载类信息,可以将类名在文件中进行配置。

2.类名.class

这种方式是通过类名的属性来获取的。

这种方式是在Class类对象阶段,根据已经记载到内存中的类信息就能知道类名,再根据类名的class属性获取Class对象。

使用场景:多用于参数传递。

3.对象名.getClass()

这种方式是根据对象的getClass()方法获取的,getClass()方法是Object提供的。

这种方式是在Runtime运行时阶段,根据已经存在的对象实例来获取其Class对象。

使用场景:多用于通过对象来获取字节码的方式。

扩展:不管使用哪一种方式获取class对象,都是同一个对象。

因为字节码文件(*.class)在程序运行过程中只会被加载一次,只会创建一个class对象。

结论验证:

//获取class对象的方法
public class ReflectTest {public static void main(String[] args) throws ClassNotFoundException {
​//1.Class.forName(String className)Class clazz1 = Class.forName("reflectdemo1.Car");
​//2.类名.classClass clazz2 = Car.class;
​//3.对象名.getClass()Class clazz3 = new Car().getClass();
​System.out.println(clazz1 == clazz2);System.out.println(clazz3 == clazz2);System.out.println(clazz1 == clazz3);
​}
}
​
输出:
true
true
true

Class对象的功能

Class对象可以让我们获取类的所有信息,包括但不限于类中定义的成员方法、成员变量、静态资源、所属包等等。接下来介绍一下Class的API(主要的)。

1.获取成员变们

Field[] getFields()

Field getField(String name)

Field[] getDeclaredFields()

Field getDeclaredField(String name)

2.获取构造方法们

Constkuctor<?>[] getConstructors()

Constructor<T> getConstructor(Class<?>... parameterTypes)

Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) Constructor<?>[] getDeclaredconstructors()

3.获取成员方法们

Method[] getMethods()

Method getMethod(String name, 类<?>... parameterTypes)

Method[] getDeclaredMethods()

Method getDeclaredMethod(string name, 类<?>... parameterTypes)

4.获取类名

string getName()

获取到对应的信息可以在根据其API进行操作。

反射使用案例

需求:实现一个框架,使其能够动态的创建指定类型的对象并执行指定类型的方法。

代码实现:

//框架:动态的创建对象,并执行相应的方法;
public class Test {public static void main(String[] args) throws Exception {//1.读取配置文件//1.1创建Properties对象Properties properties = new Properties();//1.2读取class目录下的配置文件ClassLoader classLoader = Test.class.getClassLoader();//1.3获取配置文件的输入流InputStream is = classLoader.getResourceAsStream("application.properties");//1.4将配置文件加载到properties中properties.load(is);//1.5读取配置文件中的内容String className = properties.getProperty("className");String methodName = properties.getProperty("methodName");
​//2.获取需加载类的Class对象Class<?> cls = Class.forName(className);
​//3.创建对象Object obj = cls.newInstance();
​//4.执行方法//4.1获取需要执行的方法Method method = cls.getDeclaredMethod(methodName);method.invoke(obj);
​}
}

框架中读取的application.properties配置文件如下:

className = model.Student
methodName = sleep

运行结果:

sleep....

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

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

相关文章

【网站项目】少儿编程管理系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

备战蓝桥杯---多路归并与归并排序刷题

话不多说&#xff0c;直接看题 1. 我们考虑一行一行合并&#xff0c;一共m次&#xff0c;我们合并两个并取前n小&#xff0c;那么我们怎么取&#xff1f; 我们采用分组的思想&#xff1a; 我们选第一列的min,然后把后面那个再纳入考虑&#xff0c;用优先队列实现即可。 下面…

chatGPT4无法登录

遇到问题&#xff1a;chatgpt网站上点击登录&#xff08;log in),网站就会跳转并显示&#xff1a;unable to connect 解决方法&#xff1a;不要用亚洲节点&#xff0c;亚洲节点被全面封禁&#xff0c;在全局代理中可以换成美国的节点

synchronized到底锁住的是谁?

我们使用synchronized关键字是用来实现线程同步的&#xff0c;当多个线程同时去争抢同一个资源的时候在资源上边加一个synchronized关键字&#xff0c;能够使得线程排队去完成操作。 synchronized到底锁定的是什么资源&#xff1f; 修饰方法非静态方法 &#xff0c;锁定的是方…

《UE5_C++多人TPS完整教程》学习笔记30 ——《P31 摄像机和弹簧臂(Camera And Spring Arm)》

本文为B站系列教学视频 《UE5_C多人TPS完整教程》 —— 《P31 摄像机和弹簧臂&#xff08;Camera And Spring Arm&#xff09;》 的学习笔记&#xff0c;该系列教学视频为 Udemy 课程 《Unreal Engine 5 C Multiplayer Shooter》 的中文字幕翻译版&#xff0c;UP主&#xff08;…

使用git 和 github协作开发

文章目录 github浏览器汉化插件github新建仓库git安装以及ssh配置团队创建及基本命令的使用创建团队基本命令 分支管理快速切换远程仓库地址 如何使用git && github进行协作开发&#xff0c;包括git常见基础命令 github浏览器汉化插件 在刚开始使用github的时候&#…

ubuntu安装docker,并搭建vulfocus靶场

ubuntu安装docker&#xff0c;并搭建vulfocus靶场 docker是一个容器管理的软件&#xff0c;容器背后其实就是一个进程&#xff1b;类似于一个集装箱。 docker的官方下载地址&#xff1a;Install Docker Engine on Ubuntu | Docker Documentation&#xff08;可以根据自己需要的…

【文献分享】机器学习 + 分子动力学 + 第一性原理 + 热力学性质 + 微观结构

分享一篇关于机器学习 分子动力学 第一性原理 热学性质&#xff08;密度、比热容、导热率和粘度&#xff09; 微观结构的文章。 感谢论文的原作者&#xff01; 关键词&#xff1a; 1. Deep potential 2. Machine learning 3. Molecular dynamics 4. Microscopic structu…

Linux| Awk 中“next”命令奇用

简介 本文[1]介绍了在Linux中使用Awk的next命令来跳过剩余的模式和表达式&#xff0c;读取下一行输入的方法。 next命令 在 Awk 系列教程中&#xff0c;本文要讲解如何使用 next 命令。这个命令能让 Awk 跳过所有你已经设置的其他模式和表达式&#xff0c;直接读取下一行数据。…

【无标题】【Android】Android中Intent的用法总结

2.显示地图: Java代码 Uri uri Uri.parse(“geo:38.899533,-77.036476”); Intent it new Intent(Intent.Action_VIEW,uri); startActivity(it); 3.从google搜索内容 Java代码 Intent intent new Intent(); intent.setAction(Intent.ACTION_WEB_SEARCH); intent.pu…

【C++进阶】【STL】set和map的讲解及模拟实现

&#x1fa90;&#x1fa90;&#x1fa90;欢迎来到程序员餐厅&#x1f4ab;&#x1f4ab;&#x1f4ab; 主厨&#xff1a;邪王真眼 主厨的主页&#xff1a;Chef‘s blog 所属专栏&#xff1a;c大冒险 总有光环在陨落&#xff0c;总有新星在闪烁 一、 关联式容器 在初阶阶…

github中git clone需要username和password问题

username&#xff1a;一般指你的昵称 password&#xff1a;一般指Creating a fine-grained personal access token 这个的获取办法如下&#xff08;注意&#xff0c;在11步的时候&#xff0c;记得打开你仓库对应的一些access 权限&#xff09;&#xff1a; Note: Fine-graine…

动态规划刷题(算法竞赛、蓝桥杯)--线段(线性DP)

1、题目链接&#xff1a;P3842 [TJOI2007] 线段 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) #include <bits/stdc.h> using namespace std; const int N20010; int a[N][2],f[N][2]; //a[i][0]表示l[i],a[i][1]表示r[i] int dis(int a,int b){return abs(a-b); } int…

Java中的网络编程(一)

一、网络编程概述 什么是计算机网络把不同区域的计算机&#xff08;广义&#xff09;通过通信设备和线路连接&#xff0c;可以实现数据的传输和共享的系统。实现不同计算机之间的练习&#xff0c;必须有介质连接。网络编程是干什么的聊天-->聊天软件 QQjava语言是支持网络间…

从人机界面设计黄金三法则视角看 ChatGPT 的界面设计的“好”与“坏”

热门文章推荐&#xff1a; &#xff08;1&#xff09;《为什么很多人工作 3 年 却只有 1 年经验&#xff1f;》&#xff08;2&#xff09;《一文掌握大模型提示词技巧&#xff1a;从战略到战术巧》&#xff08;3&#xff09;《AI 时代&#xff0c;程序员的出路在何方&#xff1…

数组方法汇总

数组和链表类似&#xff0c;都是用双指针&#xff0c;但数组不需要额外的指针&#xff0c;可以使用索引来当作指针。&#xff08;链表的时候要注意&#xff0c;什么时候是移动的指针&#xff0c;什么时候是改变的节点&#xff09;删除有序数组中的重复项 注意&#xff0c;本题中…

36.基于CAS实现的java类

JUC, java.util.concurrent并发工具包下。 1.原子整数 AtomicInteger AtomicLong AtomicBoolean 底层用的CAS来实现。 AtomicInteger类的incrementAndGet方法&#xff0c;addAndGet方法 public static void main(String[] args) {AtomicInteger atomicInteger new Atom…

Coursera自然语言处理专项课程04:Natural Language Processing with Attention Models笔记 Week01

Natural Language Processing with Attention Models Course Certificate 本文是学习这门课 Natural Language Processing with Attention Models的学习笔记&#xff0c;如有侵权&#xff0c;请联系删除。 文章目录 Natural Language Processing with Attention ModelsWeek 01…

c# wpf style 简单试验

1.概要 wpf style 用来控制控件的样式 2.代码 <Window x:Class"WpfApp2.Window5"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://schemas.…

MCAL SPI配置

用的是Qspi0 SpiDriver 要配置 4个选项 Spichannel SpiExternalDevice SpiJob SpiSequence Mcu 模块配置 dma配置