Java—反射

news2024/9/21 12:36:51

文章目录

  • 什么是反射
    • 反射定义
  • java创建对象的三个阶段
  • 反射过程
    • 反射第一步:获取类对象
      • 获取类对象的三种方式
    • 反射第二步:获取类信息
      • 如何获取类信息?
        • 1、获取成员变量:
        • 2、获取方法:
        • 3、获取构造器
    • 反射第三步:使用反射信息
      • 1、使用构造器 / 如何使用构造器 (构造器主要是用来创建对象的)
      • 2、方法的使用 / 如何使用方法
      • 3、变量的使用 / 如何使用变量 ----赋值、取值

——————————————————————————

什么是反射

  1. servlet是怎么运行的呢?
    ——> servlet里面没有main方法
    ——>servlet运行就用到了反射
    在这里插入图片描述
    private——私有的
    public——公开的
    protected——受保护的
    String password——default默认为空的
  2. 如何给这些数据赋值?
    2.1 创建一个对象进行赋值
    ——> 通过对象调用变量 或者 改变了的set()方法进行赋值
    ——>
    private类型的可以创建方法
    2.2 利用反射赋值
    所谓的反射赋值其实就是通过获取类信息,然后创建对象,通过对象给获取到的类信息赋值

反射定义

反射:拥有获取类信息的能力
创建对象的流程:
1、自定义java文件—>demo.java—>javac命令编译成demo.class——>通过.java命令运行到JVM内存(加载到方法区,方法区存储的是类信息 (类对象) )
(简单理解为:从类到对象的过程)
2、main方法入栈——>main方法创建类student对象——>student对象在堆内存中开辟内存空间——>堆当中,对象内部有变量的空间,存有变量(name,age,password,sno,age)

java创建对象的三个阶段

  1. 磁盘阶段 - - - - - -在d盘或在c盘等磁盘当中
  2. 类对象阶段 - - - - - -加载到内存的阶段
  3. 运行阶段
    (在堆内存那块内存区域的叫做对象,方法区当中是类对象)
    为什么一个类可以创建多个对象???——>因为类对象时刻保存在方法区当中,所以才可以时刻创建出多个对象

反射过程

反射第一步:获取类对象

获取类对象的三种方式

如何获取类对象?
方式一:通过Class.forName(“全类名”)变量来获取类对象(全类名:包名+类名)------(对应磁盘阶段,磁盘阶段就是地址形式进行存储)
方式二:类名.class ------ 类本身已经构建成了类对象,加载到磁盘当中了,因此不需要写全类名,直接类名.class就能获取类对象(对应类对象阶段)
方式三: 对象名.getClass ------ 已经生成了对象,(回退)(对应运行阶段)

反射第二步:获取类信息

如何获取类信息?

1、获取成员变量:

想获取成员变量——>通过Field类/类对象提供了一些方法
—1—>类对象.getDeclaredFields(); -------获取所有的变量,由Field[]数组进行接收
Field[] fields = class1.getDeclaredFields();
—2—>类对象.getFields(); -------获取全部的public修饰的变量,由Field[]数组进行接收
Field[] fields1 = class1.getFields();
—3—>类对象.getDeclaredField(“参数”); -------获取指定的变量,参数为指定变量名,由Field变量进行接收
Field name = class1.getDeclaredField(“name”);
—4—>类对象.getField(“参数”); -------获取指定的public修饰的变量,参数为指定变量名,由Field变量进行接收
Field password= class1.getField(“password”);
总结:方法上有Declared能获取全部的,没有Declared只能获取public修饰的变量
当sno是protected类型的时候
Field sno = class1.getField(“sno”);//会报错

2、获取方法:

—1—>类对象.getDeclaredMethods() ---------获取全部的方法,由Method[]数组接收
Method[] methods = class1.getDeclaredMethods();
—2—>类对象.getMethods() ---------获取全部的public修饰的方法,由Method[]数组接收
Method[] methods = class1.getMethods();
—3—>类对象.getDeclaredtMethod(“方法名”,“该参数的反射类型 . 该方法的参数”) ---------获取指定的方法,所有类型都可以获取,由Method变量进行接收
( 方法没有参数的时候就不写后面的"参数的类型 . 该方法的参数" )
—4—>类对象.getMethod(“方法名”,“该参数的反射类型 . 该方法的参数”) ---------获取指定的public类型修饰的方法,由Method变量进行接收

3、获取构造器

—1—>类对象.getDeclaredConstructors() ---------获取全部的构造方法,由Constructor[]数组接收
Constructor[] Constructor = class1.getDeclaredConstructors();
—2—>类对象.getConstructors() ---------获取全部的public修饰的构造方法,由Constructor[]数组接收
Constructor[] Constructor = class1.getConstructors();
—3—>类对象.getDeclaredConstructor(该参数的反射类型) ---------获取指定的构造方法,由Constructor变量接收
Constructor Constructor = class1.getDeclaredConstructor();
—4—>类对象.getConstructor(该参数的反射类型) ---------获取指定的public类型的构造方法,由Constructor变量接收
Constructor Constructor = class1.getConstructor();
所有构造器的方法名是一样的

反射第三步:使用反射信息

1、使用构造器 / 如何使用构造器 (构造器主要是用来创建对象的)

通过调用newInstance()方法来创建对象(constructor.newInstance();)
Student student = (Student) constructor.newInstance();//利用构造器生成对象
如果想要使用私有类型的数据,必须使用暴力反射
——》constructor.setAccessible(true);
对于私有的数据,必须使用暴力反射才能使用,不是私有类型的数据,不需要使用暴力反射

Class<?> clazz = Class.forName("fanshe.com.Student");
Constructor constructor = clazz.getDeclaredConstructor();
//如果想要使用私有类型的数据,必须使用暴力反射
constructor.setAccessible(true);
Student student  = (Student) constructor.newInstance();//利用构造器生成对象
System.out.println(student.sex);//这样才能使用

注:(总结)
构造器本质:创建对象
1、获取指定的构造器:如果是public修饰的,用getConstructor(“参数的反射类型”),如果是非public修饰的用getDeclaredConstructor(“该参数的反射类型”)
2、通过调用newInstance()方法来创建对象------newInstance(参数的值):如果是private类型修饰的构造器,需要暴力反射。
【获取到的指定构造器名.setAccessible(true);】
3、想使用public 和 protected 等非私有类型修饰的数据 ------ :不需要使用暴力反射

2、方法的使用 / 如何使用方法

调用invoke(对象,该方法的参数)方法 用来执行指定的方法

Class<?> clazz = Class.forName("fanshe.com.Student");
Method method = clazz.getMethod("eat",String.class);
 //为什么要创建对象??——》获取类信息是处在类对象阶段,方法、变量在第三阶段
//因为获取的类信息来源于第二阶段(对象阶段),但是要使用方法需要进入到第三阶段,创建对象,给方法内存空间才能进行调用
Student student = new Student("张三");
method.invoke(student,"水果"); 
———————————————以上是不使用反射的时候,使用反射是下面这样———————————————————————
Class<?> clazz = Class.forName("fanshe.com.Student");
Constructor construcor = clazz.getDeclaredConstructor();
constructor.setAccessible(true);
Student student = (Student) constructor.newInstance();//调用newInstance()来创建当前对象
method.invoke(student,"水果");

--------
Student.java当中有:
private Student(){

}

注:
1、获取指定所有的方法
2、创建对象 -------为什么要创建对象??——》因为获取的类信息来源于第二阶段(对象阶段),但是要使用方法需要进入到第三阶段,创建对象,给方法内存空间才能进行调用,所以需要提前创建出对象
3、如果是private类型修饰,需要暴力反射 ,如果是其他类型不需要暴力反射
4、调用invoke方法---------获取的方法类信息.invoke(对象,参数的值…);

3、变量的使用 / 如何使用变量 ----赋值、取值

Class<?> clazz = Class.forName("fanshe.com.Student");
//获取类信息
Field field = clazz.getDeclaredField();
field.setAccessible(true);
//赋值 set方法
field.set(student,"张三");
//取值 get方法
field.get(student);
System.out.println(field.get(student));//输出:张三

注:(总结)
1、获取指定的变量------如果是public修饰的变量getField(“方法名”) 、如果是非public修饰的用 类对象.getDeclareField(“name”)
2、创建对象 ------为什么要创建对象??—>因为获取的类信息来源于第二阶段(对象阶段),但是要使用变量需要进入第三阶段,创建对象,给变量内存空间才能进行调用
3、如果是privated修饰的变量需要暴力反射 获取的变量类信息.setAccessible(true)
4、赋值:变量信息.set(对象,值)
5、取值:变量信息.get(对象)

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

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

相关文章

vue学习笔记——简单入门总结(四)

文章目录1.Vue3的特性和变化1.1.创建vue3项目1.2.分析main.js变化&#xff1a;1.3.setup--组合式api的开端1.4.ref函数和reactive函数&#xff1a;1.5.watch监视属性1.5.watchEffect函数1.6.vue3生命周期&#xff1a;1.Vue3的特性和变化 1.1.创建vue3项目 1.这里我们使用脚手架…

RegAD-Registration based Few-Shot Anomaly Detection论文学习

摘要 本文为少样本异常检测&#xff08;FSAD&#xff09;&#xff0c;这是一种实用但尚未被研究的异常检测&#xff08;AD&#xff09;&#xff0c;少样本意味着在训练中只为每个类别提供有限数量的正常图像。 现有的少样本异常检测的研究主要使用的是 一类别一模型 学习范式…

李宏毅《DLHLP》学习笔记7 - Voice Conversion

视频链接&#xff1a;https://www.youtube.com/watch?vJj6blc8UijY&listPLJV_el3uVTsO07RpBYFsXg-bN5Lu0nhdG&index9&ab_channelHung-yiLee 课件链接&#xff1a;https://speech.ee.ntu.edu.tw/~tlkagk/courses/DLHLP20/Voice%20Conversion%20(v3).pdf 1. 语音转…

JAVA+MySQL 图书馆借阅信息管理系统

图书馆是当下很多大学生和有志青年学习和借阅图书的场所,图书馆每天都有大量的人员需要接待,如何能够更好的对用户的这些借阅信息进行信息化的管理是当下大多数图书馆管理人员所关心的问题 本系统是通过JAVA和MYSQL来进行开发的,通过本系统可以对图书馆内的图书信息,用户信息以…

基于PCIe的NVMe协议在FPGA中实现方法

NVMe协议是工作在PCIE的最上层协议层的&#xff0c;故需要先搞清楚PCIE。本文基于Xilinx的UltraScale&#xff0c;开发工具为Vivado2021.2。学习中以spec为主&#xff0c;其它资料辅助参考(重点介绍学习方法及资料&#xff0c;有时间再加细节)。请勿转载&#xff01; 1 PCIe学…

基于PHP+MySQL青年志愿者服务管理系统的设计与实现

志愿者管理系统能够通过互联网得到广泛的、全面的宣传,让尽可能多的人积极的参加到志愿者行列中来,不仅为需要的人提供了服务,而且锻炼了自己,志愿者是一个对社会和自己以及需要帮助的人都有很多好处的事情 PHP青年志愿者服务网站是一个公益类型的网站,系统通过PHp&#xff1a;…

HK1 BOX刷入 Armbian系统作为服务器

HK1 BOX刷入 Armbian系统作为服务器 1 安装Armbian到EMMC 硬件 HK1 BOX s905 x3 固件版本选择 Armbian_23.02.0_Aml_s905x3_bullseye_5.15.80_server_2022.12.01用usb启动&#xff0c;tf/sd有的设备不行&#xff0c;有干扰&#xff0c;有可能从TF卡无法启动系统。 用usb启…

Grid 布局实现九宫格图片动画

前言 &#x1f44f;Grid 布局实现九宫格&#xff0c;background-position设置背景图像起始位置&#xff0c;速速来Get吧~ &#x1f947;文末分享源代码。记得点赞关注收藏&#xff01; 1.实现效果 2.实现步骤 定义css变量&#xff1a;九宫格中每个宫格的长/宽为w&#xff0c…

Kafka - 14 Kafka消费者 | 分区的分配策略及再平衡 | Range | RoundRobin | Sticky | CooperativeSticky

文章目录1. 分区的分配以及再平衡2. Range 分区分配以及再平衡3. RoundRobin 分区分配以及再平衡4. Sticky 分区分配以及再平衡1. 分区的分配以及再平衡 一个consumer group中有多个consumer组成&#xff0c;一个 topic有多个partition组成&#xff0c;现在的问题是&#xff0…

【Python自然语言处理】规则分词中正向、反向、双向最大匹配法的讲解及实战(超详细 附源码)

需要源码和字典集请点赞关注收藏后评论区留言私信~~~ 一、规则分词 规则分词核心内容是建立人工专家词典库&#xff0c;通过将语句切分出的单词串与专家词典库中的所有词语进行逐一匹配&#xff0c;匹配成功则进行对象词语切分&#xff0c;否则通过增加或者减少一个字继续比较…

文件或者文件夹的忽略

文件或者文件夹的忽略 编辑项目的时候&#xff0c;将一些临时文件或者插件可以忽略上传到项目库中去。 追踪中的文件&#xff0c;不能被忽略。 首先的创建.gitignore文件&#xff0c;并且该文件需要放到项目的根目录下 接着&#xff0c;打开.gitignore文件 windows中 open d…

软件测试——分类

测试分类 一、按照测试对象划分 1、界面 界面测试UI测试 &#xff08;1&#xff09;测试软件界面元素完整性&#xff0c;正确性&#xff0c;一致性 &#xff08;2&#xff09;软件界面排版布局合理、字体、颜色 &#xff08;3&#xff09;测试界面的自适应性&#xff0c;界面…

1549_AURIX_TC275_SCU系统中的CCU模块

全部学习汇总&#xff1a; GreyZhang/g_TC275: happy hacking for TC275! (github.com) 从这一份笔记开始看一下SCU系统&#xff0c;其实这个是一个功能组合&#xff0c;其中的一个小模块又叫做SCU。因此&#xff0c;在名称上可能会有一点点绕。近段时间看相关的资料比较多&…

数据结构与算法—数组栈和链表栈

数据结构与算法—数组栈和链表栈 &#x1f308;一览众山小数据结构与算法—数组栈和链表栈栈介绍栈图解栈实现数组实现栈实现思路实现代码单链表实现栈实现思路(图解)实现代码栈总结栈力扣栈介绍 栈,存储货物或供旅客住宿的地方,可引申为仓库、中转站&#xff0c;所以引入到计算…

Java—泛型、内部类、多继承

文章目录泛型1.泛型是什么&#xff0c;使用泛型的好处2.泛型中的限定通配符和非限定通配符3.泛型擦除内部类多继承多继承使用&#xff1a;———————————————————————————泛型 1.泛型是什么&#xff0c;使用泛型的好处 ​ 泛型就是把类型参数化&…

骰子游戏-第11届蓝桥杯Scratch选拔赛真题精选

[导读]&#xff1a;超平老师计划推出Scratch蓝桥杯真题解析100讲&#xff0c;这是超平老师解读Scratch蓝桥真题系列的第94讲。 蓝桥杯选拔赛每一届都要举行4~5次&#xff0c;和省赛、国赛相比&#xff0c;题目要简单不少&#xff0c;再加上篇幅有限&#xff0c;因此我精挑细选…

Python源码剖析1-整数对象PyIntObject

1、PyIntObject 对象 [intobject.h] typedef struct {PyObject_HEADlong ob_ival; } PyIntObjectPyIntObject是一个不可变&#xff08;immutable&#xff09;对象。Python内部也大量的使用整数对象&#xff0c;我们在自己的代码中也会有大量的创建销毁整型对象的操作&#xff…

霍夫曼树:霍夫曼编码(Huffman Tree:Huffman Coding)

预计阅读时间&#xff1a;10分钟 一、简介 霍夫曼树常处理符号编写工作。根据整组数据中符号出现的频率高低&#xff0c;决定如何给符号编码。如果符号出现的频率越高&#xff0c;则给符号的码越短&#xff0c;相反符号的号码越长。 相关术语 路径&#xff1a;从书中一个节点…

Docker安装可视化管理器Portainer

Docker安装可视化管理器Portainer Portainer 提供状态显示面板、应用模板快速部署、容器镜像网络数据卷的基本操作&#xff08;包括上传下载镜像&#xff0c;创建容器等操作&#xff09;、事件日志显示、容器控制台操作、Swarm 集群和服务等集中管理和操作、登录用户管理和控制…

Linux/Windows Redis的下载与安装

Redis简介 参考视频教程: https://www.bilibili.com/video/BV13a411q753?p143 Redis下载与安装 Windows版 下载地址: https://github.com/microsoftarchive/redis/releases Linux版下载地址: https://download.redis.io/releases/ 1. Window版本 1.1 redis下载 官网下载…