【数据结构】反射,枚举你必须知道的相关知识

前言:

🌟🌟本期讲解关于反射以及枚举,希望能帮到屏幕前的你。

🌈上期博客在这里:http://t.csdnimg.cn/7D225

🌈感兴趣的小伙伴看一看小编主页:GGBondlctrl-CSDN博客

目录

📚️1.反射

1.1反射的定义

1.2反射的用途

1.3反射的相关类

1.4class类(放射机制的起源)

1.5Class类的相关的方法:

1.6获取反射对象的三种方法 

1.7反射的总结 

 📚️2.枚举

2.1背景以及定义

2.2枚举的常用方法

2.3枚举的总结 

 📚️3.反射和枚举的关系

 📚️4.总结


📚️1.反射

1.1反射的定义

对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性,既然能拿到那么,我们就可以修改部分类型信息;

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

1.2反射的用途

小编这里总结:

1.对于某些类中,存在私有的变量或者方法只能供自己类或者系统使用,我们就可以使用Java反射机制获取这些私有的属性,方法。

2. 反射最重要的用途就是开发各种通用框架。

1.3反射的相关类

1.4class类(放射机制的起源)

Java文件被编译后,生成了.class文件,JVM此时就要去解读.class文件 ,被编译后的Java件.class也被JVM解析为一个对象,这个对象就是 java.lang.Class .这样当程序在运行时,每个jav文件就最终变成了Class类对象的一个实例

1.5Class类的相关的方法:

1.获得类的相关方法:

代码实例:

 Class<?> c1 = Class.forName("Fmlambda.Student"); //拿到对象Student student = (Student) c1.newInstance();  //进行实例化

这里小编列举了两个列子

2.获得类中属性的相关方法:

getField(String name)
获得某个公有的属性对象
getFields()
获得所有公有的属性对象
getDeclaredField(String name)
获得某个属性对象
getDeclaredFields()
获得所有属性对象

代码实例:

 public static void reflectPrivateField() {try {Class<?> c3 = Class.forName("Fmlambda.Student");Field field = c3.getDeclaredField("name");field.setAccessible(true);Student student = (Student) c3.newInstance();field.set(student, "idontlovejava");System.out.println(student);} catch (NoSuchFieldException e) {throw new RuntimeException(e);} catch (ClassNotFoundException e) {throw new RuntimeException(e);} catch (InstantiationException e) {throw new RuntimeException(e);} catch (IllegalAccessException e) {throw new RuntimeException(e);}}

注解:拿到反射的类的Class对象,并且获取这个名字私有属性对象,由于name为私有属性所以得“授权”,然后进行实例化,改变这个私有属性对象的内容,最后实现打印。

3.获得类中构造器相关的方法 :

 代码实例:

public static void reflectPrivateConstructor() {try {Class<?> c2 = Class.forName("Fmlambda.Student");Constructor<?> constructor = c2.getDeclaredConstructor(String.class, int.class);constructor.setAccessible(true);Student student = (Student) constructor.newInstance("ilovejava", 20);System.out.println(student);} catch (NoSuchMethodException e) {throw new RuntimeException();} catch (InstantiationException e) {throw new RuntimeException();} catch (InvocationTargetException e) {throw new RuntimeException();} catch (IllegalAccessException e) {throw new RuntimeException();} catch (ClassNotFoundException e) {throw new RuntimeException();}}

注解:拿到反射的类的Class对象,并且获取这个类中与参数匹配的构造方法,由于为私有属性所以得“授权”,然后进行实例化,改变这个私有构造方法的内容,最后实现打印。

4.获得类中方法相关的方法: 

getMethod(String name, Class...<?> parameterTypes)
获得该类某个公有的方法
getMethods()
获得该类所有公有的方法
getDeclaredMethod(String name, Class...<?> parameterTypes)
获得该类某个方法
getDeclaredMethods()
获得该类所有方法

代码实例:

public static void reflectPrivateMethod() {Class<?> c4 = null;try {c4 = Class.forName("Fmlambda.Student");Method method = c4.getDeclaredMethod("function", String.class);method.setAccessible(true);Student student = (Student) c4.newInstance();method.invoke(student, "我是一个参数....");System.out.println();} catch (IllegalAccessException e) {throw new RuntimeException(e);} catch (InvocationTargetException e) {throw new RuntimeException(e);} catch (ClassNotFoundException e) {throw new RuntimeException(e);} catch (NoSuchMethodException e) {throw new RuntimeException(e);} catch (InstantiationException e) {throw new RuntimeException(e);}}
}

注解:拿到反射的类的Class对象,并且获取这个类中的某个私有方法,进行参数匹配,由于为私有属性所以得“授权”,然后进行实例化,改变这个私有方法的内容,最后实现打印。

1.6获取反射对象的三种方法 

第一种 ,使用 Class.forName(" 类的全路径名 "); 静态方法。
前提:已明确类的全路径名。
第二种 ,使用 .class 方法。
说明:仅适合在编译前就已经明确要操作的 Class
第三种 ,使用类对象的 getClass() 方法

代码演示:

 public static void main(String[] args) {//1.通过调用getclassStudent student = new Student();Class c = student.getClass();//2.直接通过 类名.class 的方式得到,该方法最为安全可靠,程序性能更高//这说明任何一个类都有一个隐含的静态成员变量 classClass c1 = Student.class;//3、通过 Class 对象的 forName() 静态方法来获取,用的最多,//但可能抛出 ClassNotFoundException 异常Class c2 = null;try {c2 = Class.forName("Fmlambda.Student");} catch (ClassNotFoundException e) {throw new RuntimeException();}

注意:使用forName时要抛出异常,要通过try-catch来进行捕获,并进行抛出异常。这里小编加了注解大家可以通过注解来进行查看。

1.7反射的总结 

优点:

1. 对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法
2. 增加程序的灵活性和扩展性,降低耦合性,提高自适应能力
3. 反射已经运用在了很多流行框架如:Struts、Hibernate、Spring 等等。

缺点:

1. 使用反射会有效率问题。会导致程序效率降低
2. 反射技术绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂 

 📚️2.枚举

2.1背景以及定义

枚举是在 JDK1.5 以后引入的。主要用途是:将一组常量组织起来,在这之前表示一组常量通常使用定义常量的方式

 常量举例有不好的地方,例如:可能碰巧有个数字1,但是他有可能误会为是RED,现在我们可以直接用枚举来进行组织,这样一来,就拥有了类型,枚举类型。而不是普通的整形1.

代码如下:

public static final int RED = 1;
public static final int GREEN = 2;
public static final int BLACK = 3;
//改为枚举类型后
public enum TestEnum {
RED,BLACK,GREEN;
}

2.2枚举的常用方法

values()
以数组形式返回枚举类型的所有成员
ordinal()
获取枚举成员的索引位置
valueOf()
将普通字符串转换为枚举实例
compareTo()
比较两个枚举成员在定义时的顺序

代码实现:

public enum Textdemo {RED(0,"红色"),WHITE(1,"WHITE"),GREEN(2,"GREEN"),BLACK(3,"BLACK");public int ordinal;public String color;Textdemo(int ordinal, String color) {this.ordinal = ordinal;this.color = color;}public static void main(String[] args) {Textdemo[] textdemos=Textdemo.values();  //以数组的形式返回枚举实例for (int i = 0; i <textdemos.length ; i++) {System.out.println(textdemos[i]+"索引位置是"+textdemos[i].ordinal());//进行枚举索引的打印}Textdemo textdemo=Textdemo.valueOf("RED");  //将字符串转化为枚举实例System.out.println(textdemo.color);System.out.println(WHITE.compareTo(BLACK));  //比较两个枚举在定义时的位置}

注意:这里的字符串转化为枚举时需要这个字符串时已经被定义了的枚举类型,否则就会报错。这里小编在每个方法之后都加了注解,大家可以按照注解来进行学习。

 注意:枚举的构造方法为私有方法,在编写构造方法时,为私有权限符,但是这里可以进行省略

2.3枚举的总结 

优点:

枚举常量更加简单和安全

枚举具有内置接口,代码更加简洁优美

缺点:

无法进行继承,不能进行扩展

 📚️3.反射和枚举的关系

在上述讲解中,我们知道了关于反射机制,又由于枚举的构造方法是私有的,那么我们可以通过反射来拿到枚举的实例对象呢?

此时就有如下代码:

 public static void reflectconstruct() {try {Class<?> c1 = Class.forName("Fmlambda.Textdemo");Constructor<?> constructor = c1.getDeclaredConstructor( int.class, String.class);constructor.setAccessible(true);Textdemo textdemo = (Textdemo) constructor.newInstance(5, "紫色");System.out.println(textdemo);} catch (ClassNotFoundException e) {throw new RuntimeException(e);} catch (NoSuchMethodException e) {throw new RuntimeException(e);} catch (InstantiationException e) {throw new RuntimeException(e);} catch (IllegalAccessException e) {throw new RuntimeException(e);} catch (InvocationTargetException e) {throw new RuntimeException(e);}}

此时就会发现代码报错了!!!

此时可以看到没有构造方法!!!

解释:

我们所有的枚举类,都是默认继承与 java.lang.Enum ,说到继承,继承了什么?继承了父类除构造函数外的所有东西,并且子类要帮助父类进行构造而我们写的类,并没有帮助父类构造!

枚举的内部原码构造方法:

protected Enum(String name, int ordinal) {
this.name = name;
this.ordinal = ordinal;
}

 此时我们发现父类还有两个参数没有进行子类帮助构造

所以改正后代码如下:

 constructor = c1.getDeclaredConstructor(String.class, int.class, int.class, String.class);

只用该这一行代码即可,那么此时就可以发现又报错啦~~~~

 

所以这就是源码的问题了:

源码图示:

 

这里说明的清清楚楚,就是说不能通过反射获取枚举实例,所以一切真相大白!!! 

 所以总结:枚举已经被Java的反射机制给过滤了~~~,所以枚举可以避免反射和序列化的问题。

 📚️4.总结

💬💬本期小编讲解了关于反射,枚举的相关使用方法,并且附加代码实现讲解,最后通过源码解析总结了反射和枚举之间的关系。

🌅🌅🌅~~~~最后希望与诸君共勉,共同进步!!!


                              💪💪💪以上就是本期内容了, 感兴趣的话,就关注小编吧。

                                                         😊😊  期待你的关注~~~

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

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

相关文章

linux固定ip

背景 VMware&#xff0c;centos7 查询 网关 linux指执行 ip addr 命令 拿到自动分配的ip : 192.168.150.102 [rootlocalhost ~]# cd /etc/sysconfig/network-scripts/ 执行: cd /etc/sysconfig/network-scripts/ 进入到network-scripts文件中 执行: vi ifcfg-ens33 编辑ifc…

猪八戒落地-第15届蓝桥省赛Scratch初级组真题第1题

[导读]&#xff1a;超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成&#xff0c;后续会不定期解读蓝桥杯真题&#xff0c;这是Scratch蓝桥杯真题解析第180讲。 如果想持续关注Scratch蓝桥真题解读&#xff0c;可以点击《Scratch蓝桥杯历年真题》并订阅合集&#xff0c;…

备战2024年全国大学生数学建模竞赛:湖羊养殖场空间利用率优化

目录 一、引言 二、问题分析 问题1&#xff1a;年化出栏量与羊栏缺口估算 问题2&#xff1a;最大化年化出栏量的生产计划 问题3&#xff1a;考虑不确定因素的生产计划 三、解题思路 1. 模型假设与变量设定 2. 问题1的建模与求解 3. 问题2的建模与优化 4. 问题3的建模与…

Linux驱动开发基础(sr04超声波模块)

所学来自百问网 目录 1. SR04 超声波简介 2. 硬件设计 3. 软件设计 4. 示例代码 4.1 驱动代码 4.1.1 轮询模式 4.1.2 中断模式 4.3 应用程序 4.4 Makefile 4.5 实验效果 1. SR04 超声波简介 超声波测距模块是利用超声波来测距。模块先发送超声波&#xff0c;然后接…

mate-indicators占用内存过高导致熔断

目录&#xff1a; 1、问题现象2、解决方法 1、问题现象 mate-indicators占用内存达30.9%&#xff08;内存溢出&#xff09;导致内存不足服务熔断。 2、解决方法 发现mate-indicators进程占用内存资源达到节点总内存40%&#xff0c;导致服务出现内存熔断 临时解决 systemct…

51单片机-矩阵键盘(基于LC602)

时间&#xff1a;2024.8.30 作者&#xff1a;Whappy 目的&#xff1a;手撕51&#xff08;第二遍&#xff09; 代码&#xff1a; main.c #include <REGX52.H> #include "LCD1602.h" #include "Delay.h" #include "MatrixKey.h"unsigned…

Spring及Springboot事件机制详解

程序设计的所有原则和方法论都是追求一件事——简单——功能简单、依赖简单、修改简单、理解简单。因为只有简单才好用&#xff0c;简单才好维护。因此&#xff0c;不应该以评论艺术品的眼光来评价程序设计是否优秀&#xff0c;程序设计的艺术不在于有多复杂多深沉&#xff0c;…

bigcache源码解析

1. 设计目标 Bigcache 是用 Golang 实现的本地内存缓存的开源库&#xff0c;主打的就是可缓存数据量大&#xff0c;查询速度快。 在其官方的介绍文章《 Writing a very fast cache service with millions of entries in Go 》一文中&#xff0c;明确提出的 bigcache 的设计目标…

“20人+14天”,个人开发者如何通过 Google Play 谷歌封闭测试

个人开发者的应用测试要求 为了帮助开发者提供高品质的应用从而带给用户更优质的使用体验&#xff0c;Google为所有在2023年11月13日之后创建的个人开发者账号增加了一项要求&#xff1a; 至少有20名测试人员在过去至少14天内选择持续参与测试。 满足这项要求后即可申请正式版…

SqlServer: 安装或升级到SqlServer2022

一、下载安装包。 https://info.microsoft.com/ww-landing-sql-server-2022.html?lcidzh-CN 简单注册一下之后&#xff0c;就可以下载安装包了。 或者在我的资源中下载&#xff1a; https://download.csdn.net/download/yenange/89709660 系统要求&#xff1a; https://…

<数据集>遥感航拍飞机和船舶和识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;19973张 标注数量(xml文件个数)&#xff1a;19973 标注数量(txt文件个数)&#xff1a;19973 标注类别数&#xff1a;2 标注类别名称&#xff1a;[ship,plane] 序号类别名称图片数框数1ship17575416292plane239815…

微信小程序webgl 显示图片

// wxml <view class"container"><!-- 加载地图容器 --><canvas type"webgl" id"testMap" style"width: 100%; height: 100%;" disable-scroll bindtouchstart"touchStart" bindtouchmove"touchMove&qu…

二开PHP泛目录生成源码 可生成新闻页面和关键词页面——码山侠

PS 本资源提供给大家学习及参考研究借鉴美工之用&#xff0c;请勿用于商业和非法用途&#xff0c;无任何技术支持&#xff01; 下载i5i.net 泛目录可以用来提升网站收录和排名 合理运用目录可以达到快速出词和出权重的效果 程序小 基本的服务器都带的得动 打开i5i.net——…

HarmonyOS开发实战( Beta5版)不要使用函数/方法作为复用组件的入参规范实践

概述 在滑动场景下&#xff0c;常常会对同一类自定义组件的实例进行频繁的创建与销毁。此时可以考虑通过组件复用减少频繁创建与销毁的能耗。组件复用时&#xff0c;可能存在许多影响组件复用效率的操作&#xff0c;本篇文章将重点介绍如何通过组件复用四板斧提升复用性能。 组…

惠中科技光伏清洗剂:科技创新引领绿色清洁新风尚

惠中科技光伏清洗剂&#xff1a;科技创新引领绿色清洁新风尚 在光伏产业蓬勃发展的今天&#xff0c;光伏板的清洁问题日益凸显&#xff0c;成为影响发电效率的关键因素之一。面对传统清洗方法效率低、成本高、环境影响大等痛点&#xff0c;惠中科技以科技创新为驱动&#xff0…

HIVE 数据仓库工具之第二部分(数据库相关操作)

HIVE 数据仓库工具之第二部分&#xff08;数据库相关操作&#xff09; 一、Hive 对数据库的操作1.1 创建数据库1.1.1 创建数据库语法1.1.3 示例 1.2 使用数据库1.2.1 使用数据库语法1.2.2 示例 1.3 修改数据库1.3.1 修改数据库的语法1.3.2 示例 1.4 删除数据库1.4.1 删除数据库…

【IT工具】Windows下XMind安装教程【不要米】及常用快捷键

目录 下载相关资料安装改造备注附录&#xff1a;Xmind 快捷键 下载相关资料 下载地址&#xff1a;链接: https://pan.baidu.com/s/1aSvhE_U2WKGQ3oaGvcaHqA?pwd6666 提取码: 6666 安装 双击Xmind.exe安装 安装完成之后&#xff0c;不要登录&#xff0c;关闭就行 改造 …

数据结构(单向链表)

单向链表代码 #ifndef _LINK_H_#define _LINK_H_typedef int DataType;typedef struct node {DataType data;struct node *pnext; }Link_Node_t;typedef struct link {Link_Node_t *phead;int clen; }Link_t;extern Link_t *link_creat(); extern int push_link_head(Link_t *…

2018年系统架构师案例分析试题一

目录 案例 【题目】 【问题 1】(8 分) 【问题 2】(8 分) 【问题 3】(9 分) 【答案】 【问题 1】解析 【问题 2】解析 【问题 3】解析 相关推荐 案例 阅读以下关于软件系统设计的叙述&#xff0c;在答题纸上回答问题 1 至问题 3。 【题目】 某文化产业集团委托软件公…

【flask】python框架flask的hello world

创建一个py文件&#xff0c;写如下内容 # save this as app.py from flask import Flaskapp Flask(__name__)app.route("/") def hello():return "Hello, World!"如下图 在此py文件路径下启动cmd&#xff0c;输入 flask run结果如下图 在浏览器中访问…