了解并学会使用反射

目录

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

二、反射的定义

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

四、反射的使用

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;
    }

    @Override
    public String toString() {//重写一下toString
        return "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(构造方法的参数)方法即可:

助记技巧:
记住newInstance是一个创建对象的方法也很容易,在英文中,new就是创建的意思,
instance就是对象的意思。

执行结果:

竟然报错了!

原因是:

constructor2是一个私有的构造方法

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

但是却不能直接用

解决办法:

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

即可。

运行结果:

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

执行结果:

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

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

比如获取name的类型:

执行结果:


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

运行结果:

4.Method获取类的成员方法

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

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

获取方法的返回值,

调用获取的方法等等。

执行结果:


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

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

天风证券:水电燃气价格上涨,能推动通胀么?

水电燃气价格上涨对PPI的影响更大,6%的平均价格上涨能够拉动CPI和PPI分别上涨0.3个和0.7个百分点。 近期,国内多地上调水电燃气价格 燃气价格上涨主要针对居民端。目前燃气价格实行居民用气价格限价波动非民用气市场化定价的双轨制,这使得居…

【Linux】目录和文件相关的命令,补充:centos7系统目录结构

【Linux】Linux操作系统的设计理念之一就是“一切皆文件”(Everything is a file),即将设备、文件等都当作“文件”处理。 “文件”主要类型有:目录(即文件夹),链接文档(即快捷方式…

【Linux线程】

目录 线程是操作系统的一个执行流并发编程进程并发的优劣基于线程的并发编程Linux当中的线程 线程的创建使用pthread_createpthread_join对线程进行等待pthread_exit和pthread_cancelpthread_detach线程分离注意事项 原生线程库,详谈Linux的线程pthread库管理线程 线…

云端部署Stirling PDF:构建个人App的API调用指南(附Python源码)

今天发现一个Github的开源项目,Stirling PDF,项目地址如下:https://gitcode.com/Stirling-Tools/Stirling-PDFhttps://gitcode.com/Stirling-Tools/Stirling-PDF?utm_sourceartical_gitcode目前CSDN上已经有好几个up主都介绍了这个项目&…

cocos=》 预乘、混合(黑边、白色)

简介 预乘,指的是在数据提交给GPU之前,就对纹理的RGB分量与alpha值进行计算。 预乘计算 结果颜色 源颜色值 目标颜色值 * (1 - 源 alpha 值) result source.RGB dest.RGB * (1 - source.A); 对应的颜色混合函数设置为 gl.blendFunc(gl.ONE, gl.…

英语复习之英语形近词总结

最近在练习英语口语,有很好的练习场景,和数字人对练,还能纠错,不过开口的基础需要单词量的支撑以及语法的熟悉,因为英语的语法太简单了,没啥需要复习和注意的,音标发音的问题也可以后期再纠正&a…

Angular进阶-NVM管理Node.js实现不同版本Angular环境切换

一、NVM介绍 1. NVM简介 Node Version Manager(NVM)是一个用于管理多个Node.js版本的工具。它允许用户在同一台机器上安装和使用多个Node.js版本,非常适合需要同时进行多个项目的开发者。NVM是开源的,支持MacOS、Windows和Linux…

wechat_OCR项目打包以及如何使用

📚博客主页:knighthood2001 ✨公众号:认知up吧 (目前正在带领大家一起提升认知,感兴趣可以来围观一下) 🎃知识星球:【认知up吧|成长|副业】介绍 ❤️感谢大家点赞👍&…

医学图像处理:nii格式转换(3D切片为2D)

目录 NIFTI文件结构 读取NII文件 ITK-SNAP安装 使用方法 NII转PNG NIFTI文件结构 NIFTI 格式,是一种用于存储和交换医学成像数据的文件格式,特别适用于神经影像学领域。NIFTI文件通常有两个扩展名:.nii(用于图像数据&#xf…

42.WEB渗透测试-信息收集-域名、指纹收集(4)

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 内容参考于: 易锦网校会员专享课 上一个内容:41.WEB渗透测试-信息收集-域名、指纹收集(3) 关于单域名收集内容…

基于JSP的酒店客房管理系统(二)

目录 第二章 相关技术介绍 2.1 Jsp的简介 2.2 sql server 2005 的简介 第三章 系统的分析与设计 3.1 系统需求分析 1.理解需求 2.需求分析 3.2开发及运行环境 3.3功能模块的设计 3.3.1 设计目标 3.3.2 客房管理系统前台的设计 3.3.3 操作员管…

一种算法分类方式及其应用

在计算机科学领域,算法是解决问题的有效方法,而对算法进行分类有助于理解它们的特性、优劣以及在不同场景下的应用。常见的算法分类方法,包括按设计思想、问题类型、数据结构和应用领域等,每一类算法会对应有其典型和实际应用。 算…

大数据BI可视化(Echarts组件)项目开发-熟悉交互API5.0

全局echarts对象 init初始化 registerTheme注册主题 var mCharts echarts.init(document.querySelector("div"), itcast)registerMap地图图表 connect 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8&qu…

javaFor循环-打印九九乘法表

虽然所有循环结构都可以用while或者do...while表示&#xff0c;但java提供了另一种循环语句--for循环&#xff0c;使一些循环结构变得简单。for循环语句是支持迭代的一种通用结构&#xff0c;是最有效&#xff0c;最灵活的循环结构。 先写第一列&#xff1a; 运行结果&#xf…

什么是开发者门户?最佳实践及示例

原文链接&#xff1a;https://document360.com/blog/api-developer-portal-examples 开发者门户是什么&#xff1f; DevPortal 奖的主要赞助商 Provonix 对开发者门户的定义如下&#xff1a; “开发者门户&#xff08;通常缩写为 DevPortal&#xff09;是一组 API、SDK 或其他…

【电机控制】七段式SVPWM扇区、矢量作用时间计算——对比simplefoc与Ti例程

【电机控制】七段式SVPWM扇区、矢量作用时间计算——对比simplefoc与Ti例程 文章目录 前言一、simplefoc——通过角度找扇区1.通过角度找扇区理论1.通过角度找扇区2.矢量作用时间计算3.矢量切换时间计算——七段式 2.simplefoc代码3.解读simplefoc代码1.通过角度找扇区2.矢量作…

关于YOLO8学习(四)模型转换为ncnn

前文 关于YOLO8学习(一)环境搭建,官方检测模型部署到手机 关于YOLO8学习(二)数据集收集,处理 关于YOLO8学习(三)训练自定义的数据集 简介 本文将会讲解: (1)如何通过PyCharm,进行pt模型的转换,最后输出一个适合手机端使用的模型 开发环境 win10、python 3.11…

[ARM系列]coresight(一)

原文链接 目的&#xff1a;对复杂SOC实现debug和trace的架构 典型环境 包含&#xff1a;2个ARM core&#xff0c;一个DSP&#xff0c;众多coresight组件 coresight组件实现对core、DSP的debug和trace功能 环境中包含3个通路 trace通路&#xff1a;将core和DSP内部信息输出到…

【机器学习-21】集成学习---Bagging之随机森林(RF)

【机器学习】集成学习---Bagging之随机森林&#xff08;RF&#xff09; 一、引言1. 简要介绍集成学习的概念及其在机器学习领域的重要性。2. 引出随机森林作为Bagging算法的一个典型应用。 二、随机森林原理1. Bagging算法的基本思想2. 随机森林的构造3. 随机森林的工作机制 三…

【C++】学习笔记——vector_3

文章目录 七、vector3. vector的模拟实现4. vector实现代码整合 未完待续 七、vector 3. vector的模拟实现 上篇文章我们讲解了非常 玄幻 的拷贝构造函数&#xff0c;同样的方法&#xff0c;我们也能用这种方法来实现 赋值重载函数 。 void swap(vector<T>& v) {s…