了解并学会使用反射

目录

一、反射的应用场景(简单了解)

二、反射的定义

三、关于反射的四个重要的类

四、反射的使用

1.Class获取一个class对象的方式

方式一:forName():

方式二:封装类.Class:

方式三:对象.getClass:

三种方式的使用场景

2.Constructor获取类的构造方法

3.Field获取类的字段(成员变量)

4.Method获取类的成员方法


一、反射的应用场景(简单了解)

在刚学习java时,或者还没有进行实际的项目开发时,反射运用的情况相对较少。

不过也是必须掌握的知识点,而且它也并不难。

学完之后,要运用时,回来复习复习,就差不多了。

反射的主要用途有:

1. 在日常的第三方应用开发过程中,经常会遇到某个类的某个成员变量、方法或是属性是私有的或是只对系统应用开放,这时候就可以利用Java的反射机制通过反射来获取所需的私有成员或是方法 。

2. 反射最重要的用途就是开发各种通用框架,比如在spring中,我们将所有的类Bean交给spring容器管理,无 论是XML配置Bean还是注解配置,当我们从容器中获取Bean来依赖注入时,容器会读取配置,而配置中给的 就是类的信息,spring根据这些信息,需要创建那些Bean,spring就动态的创建这些类。


二、反射的定义

Java的反射(reflection)机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法

他就相当于一个魔镜,在运行状态下,给他照一个类,就能在镜子中看到他所有的内容,包括private修饰的字段、方法等。

这种动态获取信息以及动态调用对象方法的功能称为java语言的反射(reflection)机制。

看定义有点复杂,但是说了这么多,反射实际上就是:

可以获取一个封装类中的任何字段、构造方法、成员方法的一个机制。

如图(*/ω\*):


三、关于反射的四个重要的类

要想使用反射需要铺垫很多东西,才能懂,要使用反射,掌握这些知识是必要的,先不急,慢慢来。

简单看看下面的这四个类,这类四中的有很多关于反射的成员方法,等一下会介绍的奥,留有印象就行。


四、反射的使用

,使用反射获取Student类的属性和方法为例

一下是Student类的定义:

package Test1;/*** Created with IntelliJ IDEA* Description:* User:34398* Date:2024-05-04* Time:10:33*/
public class Student {public String Happy;private String name;private int age;private Student(String happy) {//私有的有参数构造方法this.Happy = happy;}public Student() {}//无参构造方法public Student(String name, int age) {//有参构造方法this.name = name;this.age = age;}private String setHappys(String happy){//私有含参数,成员方法this.Happy=happy;System.out.println("爱好:"+this.Happy);
return happy;}private void printfName() {//私有成员方法System.out.println("名字:" + this.name);}public void printfAge() {//公有成员方法System.out.println("年龄:" + this.age);}//一下是获取字段的方法public String getHappy() {return Happy;}public void setHappy(String happy) {Happy = happy;}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() {//重写一下toStringreturn "Student{" +"Happy='" + Happy + '\'' +", name='" + name + '\'' +", age=" + age +'}';}
}

1.Class获取一个class对象的方式

获取一个class对象的方式有三种。

方式一:forName():

代码中的clazz1就是我们获取到的class对象了。

值得注意的是:

forName()中的全类名,不需要自己写,因为有时候路径名很长,自己写容易错。

我们可以用idea进行拷贝。

具体做法:

打开idea,右键Student类,选择Copy Path/Reference,点击:

然后进入这个界面,在点击Copy Reference,粘贴到forName()的参数列表中即可:

方式二:封装类.Class:

此时,clazz2也是Student的class对象。

方式三:对象.getClass:

注意,class对象只会存在一个,不会创建多个!

上述代码中的clazz1/clazz2/clazz3实际上指向的都是一个class对象:

三种方式的使用场景

第一种方式用的最多,一般都用forName()

第二种方式,一般当做一个参数进行传递        

第三种方式,在有封装类的对象时,才可以用


2.Constructor获取类的构造方法

Class类中的方法有很多,关于获取构造方法的方法就有4个。

不过好消息是,不用特意去记,因为他们的规律性极强!

助记技巧:

getConstructors()有个s,是复数形式,返回所有的公有构造方法(数组形式)

getDeclaredConstructors()多了个单词,declared,意思是声明,就是告诉编译器,他连private修饰的构造方法也要放进来

getDeclaredConstructor()和getConstructor()不带有s,是单数,所以返回一个构造方法

如果记住了这四个方法,下面获取字段和成员方法的方法基本上也就记住了。


下面是代码实操,获取类的构造方法:

1.获取所有公有构造方法:

执行结果:


2.获取所有构造方法,包括私有的:

执行结果:

此时,Student类中的所有构造方法,都在这里了。


3.获取单个构造方法:

执行结果:

小细节:

如果是要获取有参构造方法,参数要与类中的一直,顺序也不能改变,并且要在类型后面点一个class,获取字节码文件。

例如:

String.class

int.class


获取这些构造方法有什么用呢?

用处可多了,可以得到他们的访问修饰权限符、构造方法的参数等等。

idea对方法的提示和填入参数的提示,底层就是用这个实现的。


4.获取访问修饰权限符

注意:

访问权限修饰符的类型使用int型表示的,具体参照表格(了解即可):

执行结果:

1正好就是public


5.获取构造方法的参数类型

执行结果:


6.用获取的构造方法创建封装类的对象

没错,既然我们可以获取封装类的构造方法,那么就可实例化一个封装类的对象.

在Constructor类中调用newInstance(构造方法的参数)方法即可:

执行结果:

竟然报错了!

原因是:

constructor2是一个私有的构造方法

虽然我们可以通过getDecclaredConstructor()获取这个构造方法,

但是却不能直接用

解决办法:

constructor2.setAccssible(true)//临时取消权限校验

即可。

运行结果:

3.Field获取类的字段(成员变量)

执行结果:

 

其他的比如,所有字段/访问权限修饰符/数据类型等,

格式和获取构造方法的方式可以说一模一样,这里就不多演示了,都是写重复的方式,所以说反射其实并不难。

比如获取name的类型:

执行结果:


另外,Field还有特有的方法,可以获取并且修改成员变量记录的值(在new了一个封装类的对象后)

运行结果:

4.Method获取类的成员方法

其实写完前三个,这个就没有什么好写的了几乎就是十以内的加减法,换着数字考你。

值得注意的是,Method类拥有独属于自己的方法,例如:
获取方法抛出的异常,

获取方法的返回值,

调用获取的方法等等。

执行结果:


以上就是这篇文章的全部内容,自己动手试试,这块内容还是很看实践的。如果可以独立把代码敲出来,说明你就掌握的差不多了。

关于反射这块内容如果还有不清楚的,小编很推荐看一下B站的黑马程序员,讲的很细节,基本都是嚼碎了,喂给你的。

B站链接:java进阶教程进阶教程

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

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

相关文章

【stomp 实战】Spring websocket 用户订阅和会话的管理源码分析

通过Spring websocket 用户校验和业务会话绑定我们学会了如何将业务会话绑定到spring websocket会话上。通过这一节,我们来分析一下会话和订阅的实现 用户会话的数据结构 SessionInfo 用户会话 用户会话定义如下: private static final class Sessio…

怎么让电脑耳机和音响都有声音

电脑耳机音响不能同时用没声音怎么办 一般来说,重新开机后问题能够得到解决。右击“我的电脑”---“属性”---“硬件”---“设备管理器”,打开“声音、视频和游戏控制器”有无问题,即看前面有没有出现黄色的“”。 如果您的 电脑 耳机能正常…

VMware虚拟机中ubuntu使用记录(4)—— 如何在VMware虚拟机中调用本机电脑的摄像头

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、虚拟机调用本机摄像头(1) 启动VMware USB 服务(2) 连接本机摄像头(3) 测试摄像头的连接 前言 通过配置虚拟机调用本机摄像头,用户可以在虚拟机…

redis集群的创建安装与配置,以及维护

一、redis集群配置 port 7000 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes 二、安装ruby(ruby可以充当redis客户端的角色) yum -y install ruby ruby-devel rubygems rpm-build gem install …

【SQL】根据条件分组,并根据条件取最大的这一条数据

数据,当字段A相同时,取字段B数值大的这一条数据 ABC123114223234 期望结果 ABC123234 Oracle SELECT A, B, C FROM (SELECT A, B, C,ROW_NUMBER() OVER (PARTITION BY A ORDER BY B DESC) AS rnFROM 表名 ) WHERE rn 1; MySql SELECT t1.A, t1.B,…

Redis---------实现商品秒杀业务,包括唯一ID,超卖问题,分布式锁

订单ID必须是唯一 唯一ID构成: 代码生成唯一ID: import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Component; import java.time.LocalDateTime; import java.time.ZoneOffset; import java.tim…

Java内存中的垃圾回收是如何实现的

Java内存中的垃圾回收是通过Java虚拟机(JVM)的垃圾收集器(Garbage Collector)来实现的。垃圾收集器自动管理Java堆内存中的对象,通过识别并回收不再使用的对象来释放内存空间,从而防止内存泄漏和内存溢出等…

JAVASE相关知识补充

基础知识 类作为成员变量类型: 接口作为成员变量类型: 接口作为方法的参数或者返回值 Object类: java.lang.object 类object是类层次结构的超(根)类 每个类都是用object作为父类 所有对象包括数组都实现这个类的…

【论文阅读】Learning Texture Transformer Network for Image Super-Resolution

Learning Texture Transformer Network for Image Super-Resolution 论文地址Abstract1. 简介2.相关工作2.1单图像超分辨率2.2 Reference-based Image Super-Resolution 3. 方法3.1. Texture TransformerLearnable Texture Extractor 可学习的纹理提取器。Relevance Embedding.…

什么是binutils-arm-linux-gnueabi

2024年5月3日,周五晚上 binutils-arm-linux-gnueabi 是针对 ARM 架构的 Linux 系统开发的 GNU Binutils 工具链。Binutils 是一组用于汇编、链接和转换目标文件的工具,包括 as (汇编器)、ld (链接器)、objcopy (目标文件转换工具) 等。 binutils-arm-li…

【Nginx 开发】Nginx高可用集群

配置集群 高可用集群配置高可用集群 高可用集群 为什么需要配置Nginx集群: 在实际开发过程中Nginx也有可能宕机,如果我们能够将Nginx配置成高可用,当Nginx宕机之后,在集群中我们可以将请求转发到从Nginx服务器当中,由…

【代码随想录——数组篇】

代码随想录——数组篇 2. 二分查找3. 移除元素4. 有序数组的平方5. 长度最小的子数组6. 螺旋矩阵II 2. 二分查找 力扣题目链接 前提: 有序数组数组中无重复元素 代码: (版本一)左闭右闭区间 class Solution {public int sea…

AcWing 850. Dijkstra求最短路 II

Problem: AcWing 850. Dijkstra求最短路 II 文章目录 思路解题方法复杂度Code 思路 这是一个经典的 Dijkstra 算法问题,我们需要找到从点 1 到点 n 的最短路径。Dijkstra 算法是一种贪心算法,它总是选择当前未访问过的节点中距离最短的一个,然…

什么是Boot Loader?为什么需要Boot Loader?

2024年5月4日,周六下午 什么是Boot Loader 引导加载程序(Boot Loader)是一种软件,位于计算机系统的启动过程中,其主要功能是在系统上电后负责引导加载操作系统内核。Boot Loader通常存储在计算机系统的固化存储设备&a…

代码随想录算法训练营第14天 | 144. 二叉树的前序遍历 | 145. 二叉树的后序遍历 | 94. 二叉树的中序遍历

144. 二叉树的前序遍历 解1: 递归 void preorder(struct TreeNode* root, int *array, int *idx) {if (root ! NULL) {array[(*idx)] root->val;preorder(root->left, array, idx);preorder(root->right, array, idx);} }int* preorderTraversal(struct TreeNode* …

【代码随想录】day49

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、121. 买卖股票的最佳时机二、122.买卖股票的最佳时机II 一、121. 买卖股票的最佳时机 class Solution { public:int maxProfit(vector<int>& prices…

Qt QImageWriter类介绍

1.简介 QImageWriter 用于写入图像文件的类。它提供了将 QImage 对象保存到不同图像格式文件的功能&#xff0c;包括但不限于 PNG、JPEG、BMP 等。QImageWriter 可以将图像写入文件&#xff0c;也可以写入任何 QIODevice&#xff0c;如 QByteArray&#xff0c;这使得它非常灵活…

pytorch简单神经网络模型训练

目录 一、导入包 二、数据预处理 三、定义神经网络 四、训练模型和测试模型 五、程序入口 一、导入包 import torch import torch.nn as nn import torch.optim as optim # 导入优化器 from torchvision import datasets, transforms # 导入数据集和数据预处理库 from tor…

python中type,object,class 三者关系

type,object,class 三者关系 在python中&#xff0c;所有类的创建关系遵循&#xff1a; type -> int -> 1 type -> class -> obj例如&#xff1a; a 1 b "abc" print(type(1)) # <class int> 返回对象的类型 print(type(int)) …