当前位置: 首页 > news >正文

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

前言:

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

🌈上期博客在这里: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.总结

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

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


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

                                                         😊😊  期待你的关注~~~

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 1、Django Admin学习模型
  • yolov8目标检测pyside6可视化图形界面+检测源码ui文件——用于计数统计
  • Elasticsearch:使用 LTR 进行个性化搜索
  • Redis String 类型详解:操作命令、底层编码与使用案例
  • 当采用 JSON 格式的数据进行响应时,对象是否需要序列化取决于什么?
  • 【赵渝强老师】MongoDB的WiredTiger存储引擎
  • 苹果系统(MacOS)资源管理器和终端的来回切换
  • Centos7通过reposync搭建本地Yum源
  • 非局部均值降噪算法(NLM)原理及实现
  • 冒泡排序;选择排序;插入排序;快排;判断大小端;位运算
  • 【C++算法】分治(快排 归并)
  • 中国各城市、各区县、各省份-PM2.5相关数据(1998-2021年)
  • 零基础5分钟上手亚马逊云科技 - AI模型内容安全过滤
  • Flink 配置文件的深度解读
  • 评价决策类——层次分析法+数学建模+实战分析
  • Google 是如何开发 Web 框架的
  • “Material Design”设计规范在 ComponentOne For WinForm 的全新尝试!
  • 【挥舞JS】JS实现继承,封装一个extends方法
  • Elasticsearch 参考指南(升级前重新索引)
  • Flex布局到底解决了什么问题
  • isset在php5.6-和php7.0+的一些差异
  • JavaScript对象详解
  • JavaScript中的对象个人分享
  • Java到底能干嘛?
  • Linux链接文件
  • Mocha测试初探
  • Mysql数据库的条件查询语句
  • 翻译--Thinking in React
  • 你不可错过的前端面试题(一)
  • 配置 PM2 实现代码自动发布
  • 扫描识别控件Dynamic Web TWAIN v12.2发布,改进SSL证书
  • 使用阿里云发布分布式网站,开发时候应该注意什么?
  • 手机端车牌号码键盘的vue组件
  • 提升用户体验的利器——使用Vue-Occupy实现占位效果
  • 栈实现走出迷宫(C++)
  • # Redis 入门到精通(八)-- 服务器配置-redis.conf配置与高级数据类型
  • # SpringBoot 如何让指定的Bean先加载
  • #、%和$符号在OGNL表达式中经常出现
  • #include<初见C语言之指针(5)>
  • #NOIP 2014# day.1 T2 联合权值
  • #单片机(TB6600驱动42步进电机)
  • #设计模式#4.6 Flyweight(享元) 对象结构型模式
  • $nextTick的使用场景介绍
  • $var=htmlencode(“‘);alert(‘2“); 的个人理解
  • (1)Nginx简介和安装教程
  • (35)远程识别(又称无人机识别)(二)
  • (8)Linux使用C语言读取proc/stat等cpu使用数据
  • (9)目标检测_SSD的原理
  • (java)关于Thread的挂起和恢复
  • (安全基本功)磁盘MBR,分区表,活动分区,引导扇区。。。详解与区别
  • (博弈 sg入门)kiki's game -- hdu -- 2147
  • (附源码)计算机毕业设计SSM保险客户管理系统
  • (论文阅读40-45)图像描述1
  • (十三)Java springcloud B2B2C o2o多用户商城 springcloud架构 - SSO单点登录之OAuth2.0 根据token获取用户信息(4)...
  • (实战篇)如何缓存数据