反射,枚举,lambda表达式
目录
1、反射
1.1 基本概念
1.2 反射相关的类
1.3 创建 Class 对象
1.4 反射的使用
1.4.1 通过反射创建对象:
1.4.2 获取私有的构造方法
1.4.3 获取私有的成员变量
1.4.4 获取私有的方法
1.5 总结
2、枚举
2.1 认识枚举
2.2 使用枚举
2.3 枚举与反射的那些事
3、Lambda 表达式
3.1 认识 Lambda 表达式
3.2 语法
3.3 函数式接口
3.4 Lambda 的基本使用
1、反射
1.1 基本概念
Java的反射(reflection)机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性,既然能拿到,那么我们就可以修改部分类型信息;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射(reflection)机制。
1.2 反射相关的类
类名 | 用途 |
---|---|
Class 类 | 代表类的实体,在运行的Java程序中表示类和接口 |
Field 类 | 代表类的成员变量/类的属性 |
Method 类 | 代表类的方法 |
Constructor 类 | 代表类的构造方法 |
每个类里面都有很多相关的方法啊,这里具体的方法我就不一一列举出来了,详细的可以去查看 Java 的官方文档。
1.3 创建 Class 对象
创建一个 Class 对象,通常使用以下三种方法:
1. 调用某个对象里面的 getClass 方法:
public static void main(String[] args) {Student student = new Student();Class<?> c1 = student.getClass();
}
2. 采取类名.class的方法:
public static void main(String[] args) {Class<?> c2 = Student.class; //这种方法说明每个类默认隐式包含一个静态的成员变量 class
}
3. 通过 Class.forName() 获取:
public static void main(String[] args) {Class<?> c3 = null;try {c3 = Class.forName("Student");} catch (ClassNotFoundException e) {e.printStackTrace();}
}
注意:这个 forName 中要放传入类的完整路径,比如如果是 String 的话,即:java.lang.String
1.4 反射的使用
这里我们自定义一个 Student 类:
public class Student {private String name;private int age;public Student() {System.out.println();}private Student(String name, int age) {this.name = name;this.age = age;}public void eat() {System.out.println(name + "正在吃饭!");}private void sleep() {System.out.println(name + "正在睡觉!");}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}
}
1.4.1 通过反射创建对象:
public static void reflectClassDemo() {try {Class<?> c = Class.forName("Student");Object objectStudent = c.newInstance();} catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) {e.printStackTrace();}
}
1.4.2 获取私有的构造方法
public static void reflectPrivateConstructor() {try {Class<?> c = Class.forName("Student");Constructor<?> constructor = c.getDeclaredConstructor(String.class, int.class);constructor.setAccessible(true); //设置为true后可修改访问权限Object objectStudent = constructor.newInstance("张三", 12);System.out.println(objectStudent);} catch (ClassNotFoundException | NoSuchMethodException | InvocationTargetException | IllegalAccessException | InstantiationException e) {e.printStackTrace();}
}
1.4.3 获取私有的成员变量
public static void reflectPrivateField() {try {Class<?> c = Class.forName("Student");Field field = c.getDeclaredField("name"); //获取名为 name 的成员变量field.setAccessible(true);Object student = c.newInstance();field.set(student, "张三"); //将 student 对象的name 设置成 "张三"System.out.println(field.getName());} catch (ClassNotFoundException | NoSuchFieldException | IllegalAccessException | InstantiationException e) {e.printStackTrace();}
}
1.4.4 获取私有的方法
public static void reflectPrivateMethod() {try {Class<?> c = Class.forName("Student");Method method = c.getDeclaredMethod("eat");method.setAccessible(true);//方法有参数的写法://Method methodStudent = classStudent.getDeclaredMethod("function",String.class);Object objectStudent = c.newInstance();Student student = (Student)objectStudent;System.out.println("私有方法方法名: " + method.getName());method.invoke(objectStudent); // 调用获取到的方法, student对象中的} catch (InstantiationException | InvocationTargetException | NoSuchMethodException | IllegalAccessException | ClassNotFoundException e) {e.printStackTrace();}
}
1.5 总结
在反射眼中,对应任意一个类,都能够知道这个类的属性和方法,对于任意一个对象,都能调用它任意一个方法, 这样使程序的灵活性大大提高,以及可扩展性,但是这样一来,似乎就在告诉大家,之前封装的一些方法和属性在反射面前就是一个摆设。
反射是一把双刃剑,是一种非常规的编程手段,不到必要的时候,不建议使用反射,使用反射会有效率问题。会导致程序效率降低,而且反射技术绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂 。
2、枚举
2.1 认识枚举
枚举顾名思义,一一列举,作用将一组常量组织起来,Java中常量就是常量,并没有常变量这种说法,利用我们现在的知识,如果让你定义三个常量,分别表示 红色,黑色,绿色,你可能会这样定义:
public static final int RED = 1;
public static final int BLACK = 3;
public static final int GREEN = 3;
这样的话,代码中出现的 1,有可能会被误认为是 RED,是可能会出现歧义的,于是就有一种类型枚举来进行组织:
public enum MyEnum {RED, BLACK, GREEN;
}
这样里面定义的每个都是枚举类型,不再是普通的数字了,我们自己写的 enum 会默认继承 Enum 类,所以不用显示的去继承 Enum 这个抽象类。
2.2 使用枚举
public static void main(String[] args) {MyEnum myEnum = MyEnum.BLACK;switch (myEnum) {case RED:System.out.println("红色!");break;case BLACK:System.out.println("黑色!");break;case GREEN:System.out.println("绿色!");break;default:System.out.println("其他颜色!");break;}
}
使用场景:错误状态码,消息类型,颜色的划分,状态机等等....
Enum 类的常用方法:
方法名称 | 描述 |
---|---|
values() | 以数组的形式返回枚举类型的所有成员 |
ordinal() | 获取枚举成员的索引位置 |
valueOf() | 将普通字符串转换为枚举类型 |
compareTo() | 比较两个枚举成员在定义时候的顺序 |
枚举是一种类型,也就是Java中的枚举就是一个类,那么就可以这样去写代码:
public enum MyEnum {RED("红色", 1), BLACK("黑色", 2), GREEN("绿色", 3);private String name;private int key;private MyEnum(String name, int key) {this.name = name;this.key = key;}
}
枚举的构造方法默认是私有的.
枚举常量是更简单安全的,安全体现在哪,马上就说到了,而且枚举拥有内置方法,使用起来方便,缺点也有,由于Java中支持单继承,因此枚举类型不能再继承其他类,无法扩展。
2.3 枚举与反射的那些事
通过反射,能否拿到枚举的私有构造方法呢?我们写个代码来测试一下:
public class TestMyEnum {public static void main(String[] args) {try {Class<?> c = Class.forName("MyEnum");Constructor<?> constructor = c.getDeclaredConstructor(String.class, int.class);constructor.setAccessible(true);Object myEnum = constructor.newInstance("红色", 123);} catch (Exception ex) {ex.printStackTrace();}}
}
这里居然报错了,报错信息提示没有该构造方法???为什么会没有呢,我们的 MyEnum 默认继承了 Enum 类,实例化子类对象的时候,先调用父类的构造方法,那么这里我们就去看一下 Enum 的构造方法。
Enum 只有这一个构造方法,还带有两个参数,但是在 JavaSE 的学习中,如果在子类的构造方法中,没有显式写明 super(),则会在子类构造方法第一行默认有 super(),也就是调用父类的无参构造,枚举比较特殊虽然我们写的是两个,但默认他还添加了 name,和 ordinal 参数。也就是说,我们需要提供四个参数:
Constructor<?> constructor = c.getDeclaredConstructor(String.class, int.class, String.class, int.class);
constructor.setAccessible(true);
Object myEnum = constructor.newInstance("红色", 123, "红色", 321);
这里还是报错了,但是这里的报错是第10行的,newInstance 方法报错,那么我们就进入该方法源码去一看究竟:
在JavaSE语法上,if 中的 & 会被认为 &&,所以枚举在这里被过滤了,这也就是你不能通过反射获取到枚举类的实例!
所以在这里可以发现,枚举是安全的,可以避免反射的问题。
3、Lambda 表达式
3.1 认识 Lambda 表达式
Lambda表达式是Java SE 8中一个重要的新特性。lambda表达式允许你通过表达式来代替功能接口。 lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码 块)。 Lambda 表达式(Lambda expression),基于数学中的 λ 演算得名,也可称为闭包(Closure)。
3.2 语法
基本语法: (parameters) -> expression 或 (parameters) -> { statements; }
Lambda表达式由三部分组成:
- 1. paramaters:类似方法中的形参列表,这里的参数是函数式接口里的参数。这里的参数类型可以明确的声明 也可不声明而由JVM隐含的推断。另外当只有一个推断类型时可以省略掉圆括号。 2. ->:可理解为“被用于”的意思
- 3. 方法体:可以是表达式也可以代码块,是函数式接口里方法的实现。代码块可返回一个值或者什么都不反 回,这里的代码块块等同于方法的方法体。如果是表达式,也可以返回一个值或者什么都不反回。
3.3 函数式接口
函数式接口:一个接口中,只有一个抽象方法。
@FunctionalInterface 注解:如果我们在某个方法上声明了该注解,那么编译器就会按照函数式接口的定义来要求该接口。如果不符合函数式接口的语法,那么则会报错!
例子:
@FunctionalInterface
public interface TestFuncInterface {void work();
}
也可也这样写:
@FunctionalInterface
public interface TestFuncInterface {void work();default void test() {System.out.println("hello");}
}
在 JDK 1.8 中,default 默认方法可以有具体的实现。
3.4 Lambda 的基本使用
//无返回值无参数
@FunctionalInterface
interface NoParameterNoReturn {void work();
}
//无返回值一个参数
@FunctionalInterface
interface OneParameterNoReturn {void work(int a);
}
//无返回值多个参数
@FunctionalInterface
interface MoreParameterNoReturn {void work(int a,int b);
}
//有返回值无参数
@FunctionalInterface
interface NoParameterReturn {int work();
}//有返回值一个参数
@FunctionalInterface
interface OneParameterReturn {int work(int a);
}
//有返回值多参数
@FunctionalInterface
interface MoreParameterReturn {int work(int a,int b);
}public class TestLambda {public static void main(String[] args) {NoParameterNoReturn n1 = () -> System.out.println("NoParameterNoReturn");n1.work();// 只有一个参数, 可以省略小括号OneParameterNoReturn n2 = x -> {System.out.println(x + "OneParameterNoReturn");System.out.println("多条语句则不能省略大括号!!!");};n2.work(5);MoreParameterNoReturn n3 = (x, y) -> System.out.println(x + y + "OneParameterNoReturn");n3.work(5, 8);NoParameterReturn n4 = () -> 88; //只有 return 一条语句可以省略 returnint ret1 = n4.work();OneParameterReturn n5 = (x) -> {System.out.println("OneParameterReturn");return x + 10; //多条语句时, return 和 {} 都不能省略};int ret2 = n5.work(12);// 如果不省略形参类型, 必须都不省略, 省略的话必须全部省略MoreParameterReturn n6 = (int x, int y) -> (x + y + 8);int ret3 = n6.work(5, 5);}
}
Lambda表达式的优点很明显,在代码层次上来说,使代码变得非常的简洁。缺点也很明显,代码不易读。至于 Lambda 的更多使用,会在后续文章中慢慢体现出来。这里我们了解下语法即可。
优点:
- 代码简洁,开发迅速
- 方便函数式编程
- 非常容易进行并行计算
- ava 引入 Lambda,改善了集合操作(比如传比较器)
缺点:
- 代码可读性变差
- 在非并行计算中,很多计算未必有传统的 for 性能要高
- 不容易进行调试
下期预告:【MySQL】数据库的基本认识
相关文章:
反射,枚举,lambda表达式
目录 1、反射 1.1 基本概念 1.2 反射相关的类 1.3 创建 Class 对象 1.4 反射的使用 1.4.1 通过反射创建对象: 1.4.2 获取私有的构造方法 1.4.3 获取私有的成员变量 1.4.4 获取私有的方法 1.5 总结 2、枚举 2.1 认识枚举 2.2 使用枚举 2.3 枚举与反射…...
.Net Core对于RabbitMQ封装分布式事件总线
首先我们需要了解到分布式事件总线是什么; 分布式事件总线是一种在分布式系统中提供事件通知、订阅和发布机制的技术。它允许多个组件或微服务之间的协作和通信,而无需直接耦合或了解彼此的实现细节。通过事件总线,组件或微服务可以通过发布…...
GPIO功能描述
GPIO 文章目录 GPIO1. 功能描述1.1 OSCI/OSCO 引脚1.3 HSEIN/HSEOUT引脚1.2 Bit-Band1.4 VRTCAFx引脚1.5 EWKUPx引脚1.6 QSPI0 引脚1.7 LVDIN引脚1.8 SARADC引脚1.9 ADCIN引脚2. 测试项描述2.1 PAD Location2.2 LBOR和BOR复位2.3 驱动能力2.4 模拟态\高阻态2.5 SWD\JTAG2.6 输出…...
指派问题与匈牙利法讲解
指派问题概述:实际中,会遇到这样的问题,有n项不同的任务,需要n个人分别完成其中的1项,每个人完成任务的时间不一样。于是就有一个问题,如何分配任务使得花费时间最少。通俗来讲,就是n*n矩阵中&a…...
day5——冒泡排序,选择排序和插入排序的学习
选择排序冒泡排序插入排序 选择排序 选择排序的基本思路就是: 首先假定第一个的下表为所有元素中最小的一个, 然后用后面的每一个元素跟这个元素进行比较, 如果后面的元素比这个元素更小一点, 那么就将找到的最小的元素的下标和…...
Windows 数据类型 (Windows Data Types)
参考:https://learn.microsoft.com/en-us/windows/win32/winprog/windows-data-types 要求 要求值最低受支持的客户端Windows XP [仅限桌面应用]最低受支持的服务器Windows Server 2003 [仅限桌面应用]HeaderBaseTsd.h;WinDef.h;WinNT.hAPIENTRY 系统函数的调用约…...
九龙证券|本周5只新股申购,特斯拉、蔚来、理想的供应商来A股了!
据现在组织,2月13日到17日共有5只新股申购,其间上证主板2只,深证主板1只,北交所2只。 2月14日发动打新的深证主板新股多利科技成立于2010年,是一家专心于轿车冲压零部件及相关模具的开发、出产与出售的企业。从2020年…...
设计模式(持续更新)
本文主要是记录java的设计模式在实际工作中的应用案例,或者是对设计模式的个人理解及备忘 一、单例模式Singleton 工作场景(静态类): 在外部系统对接中,需要调用外部系统A的接口,但是接口是有身份校验的…...
Prometheus 告警规则
Prometheus 告警规则 Prometheus官方内置的第三方报警通知包括:邮件、 即时通讯软件(如Slack、Hipchat)、移动应用消息推送(如Pushover)和自动化运维工具(例如:Pagerduty、Opsgenie、Victorops) Promethe…...
mulesoft MCIA 破釜沉舟备考 2023.02.13.02
mulesoft MCIA 破釜沉舟备考 2023.02.13.03 1. According to MuleSoft, which deployment charcateristic applies to a microservices application architecture?2. A mule application designed to fulfil two requirements3. A mule application must periodically process…...
获取DLL运行时路径的方法
之前项目中发现的问题,记录下解决方案1. 问题背景OVVRNTool项目中,底层图像基本操作功能由DLL库函数提供,上层基于DLL封装了两个应用CMD和GUI,然后通过Qt打包分发;发布是直接采用绿色免安装的方式打包,具体…...
“华为杯”研究生数学建模竞赛2006年-【华为杯】D题:学生面试中教师安排的优化与算法(附获奖论文)
赛题描述 高校自主招生是高考改革中的一项新生事物,现在仍处于探索阶段。某高校拟在全面衡量考生的高中学习成绩及综合表现后再采用专家面试的方式决定录取与否。该校在今年自主招生中,经过初选合格进入面试的考生有N人,拟聘请老师M人。每位学生要分别接受4位老师(简称该学…...
【JavaScript】复习 【对象参数】【函数参数】
js不会检查任何参数类型,任何参数都可以作为参数传递 1、对象参数 改变量随便改,改对象要看这个对象是不是有多个变量同时指向这个对象 const 用来定义常量,只能赋值一次。 变量------->对象------->属性 被const修饰的对象 …...
如何批量提取文件名到excel表格?
批量提取文件名到excel表格?关于这个问题相信很多人都遇到过,大多数人在第一次碰到的时候都不知道如何下手,大家都会立即在百度里面搜索相关方法教程,小编也试着搜索了一下,发现找到的很多方法都大同小异,需…...
CUDA线程层次一文搞懂|参加CUDA线上训练营
设备术语 Host:CPU 和 内存 (host memory)Device:GPU 和显存 (device memory) CUDA 线程层次 CUDA 线程层次分为: Thread 所有线程执行相同的核函数并行执行 Thread Block 执行在一个 Streaming Multiprocessor (SM)…...
Linux文件默认权限:umask
umask就是指定目前用户在建立文件或目录时候的权限默认值 查看方式有两种:一种可以直接输入umask,就可以看到数字类型的权限设置值,一种则是加入umask后加入-S(Symbolic)选项,就会以符号类型的方式来显示出…...
SonicWall:请立即修复SMA 1000 漏洞
近日,网络安全供应商SonicWall发布了关于安全移动访问 (SMA) 1000设备的三个安全漏洞的紧急报告,其中包括一个高威胁性的身份验证绕过漏洞。SonicWall指出,攻击者可以利用这些漏洞绕过授权,并可能破坏易受攻击的设备。 从报告中可…...
基于VS调试分析 + 堆栈观察问题代码段
文章目录问题代码段1 —— 阶乘之和问题代码段2 —— 越界的危害① 发现问题② 分析问题③ 思考问题【⭐堆栈原理⭐】④ 解决问题【DeBug与Release】👨程序员与测试人员👩✒总结与提炼问题代码段1 —— 阶乘之和 先来看一道C语言中比较基础的题目&#x…...
QFramework框架学习
主要学习内容TypeEventSystemActionKitTimer类1、TypeEventSystem-适用于一个条件触发,多个组件响应的情况例如:动物园系统中,点击肉食动物按钮,动物园中有肉食属性的动物都进行显示。步骤:1、动物自身脚本上进行判断是…...
移动OA系统,联动企业协作让办公高效无间断
移动oa系统,近年来随着企业办公节奏的变化及人们个性化办公需求的增加迎来了快速发展。一方面,它兼具OA系统诸多优势,既凝聚了企业基础管理工作,联动了企业协作、沟通交流,又进一步提高了企业的综合实力与市场竞争力。…...
结构体熟练掌握--实现通讯录
魔王的介绍:😶🌫️一名双非本科大一小白。魔王的目标:🤯努力赶上周围卷王的脚步。魔王的主页:🔥🔥🔥大魔王.🔥🔥🔥 ❤️…...
腾讯云CVM服务器购买流程手把手方法教程攻略
购买腾讯云服务器有两种方式。一种是在官方活动中,简单方便,但ECS配置相对固定;另一种是在ECS页面定制购买。配置选项丰富,但地理可用性区域、计费模式、CPU内存实例规格、映像系统、存储系统磁盘、网络带宽和安全组的选择更为复…...
九龙证券|“春季躁动”行情要来?1月新增投资者数大增
新增投资者数量在上一年12月触及多年新低后,2023年1月份开端呈现反弹。 在新增投资者数量之外,近段时刻以来,包含A股商场股票成交额、北向资金净买入额、两融资金规划及成交额在内多个商场目标也呈现回暖的特征,目前A股商场交投氛…...
C语言(按位运算符和位移运算符)
目录 编辑 一.按位运算符 1.二进制反码或按位取反:~ 2.按位与:& 3.按位或:| 4.按位异或:^ 二.位移运算符 1.左移: << 2.右移: >> 一.按位运算符 C有四个按位逻辑运算符都用于整…...
删掉的照片怎么恢复?
每一张照片都是生活,留住每一个人的回忆。而这些有意义的照片,我们都会把它保存在我们的手机或电脑上,始终伴随着我们。但无论是手机还是电脑,都是需要时不时清理一下的。如果是清理垃圾图片时,不小心删除了需要的图片…...
【java】40 个 SpringBoot 常用注解(建议收藏)
本文目录一、Spring Web MVC 注解Spring Web MVC 注解RequestMappingRequestBodyGetMappingPostMappingPutMappingDeleteMappingPatchMappingControllerAdviceResponseBodyExceptionHandlerResponseStatusPathVariableRequestParamControllerRestControllerModelAttributeCross…...
【JMC】SMILES‑based deep generative scafold decorator for de‑novo drug design
SMILES-based deep generative scaffold decorator for de-novo drug design 基于SMILES的利用Fragment的分子生成模型 https://github.com/undeadpixel/reinvent-scaffold-decorator 1.背景 深度生成模型因其可以从有限的数量中生成新数据,目前已成功应用于生成…...
全链路异步,让你的 SpringCloud 性能优化10倍+
背景 随着业务的发展,微服务应用的流量越来越大,使用到的资源也越来越多。 在微服务架构下,大量的应用都是 SpringCloud 分布式架构,这种架构,总体是全链路同步模式。 同步编程模式不仅造成了资源的极大浪费&#x…...
131.《router v 5 与 react-router v 6》
文章目录1.什么是路由2.路由分类3.react-router-dom的理解4. react-router-dom相关API5.其他6. react-router5 路由基本使用1.效果2.代码App.js一级路由home.js下的二级路由7.路由传参的三种方式8.react-router6 基本使用1.一级路由2.二级路由3.hooksuseRoutesuseParamsuseSear…...
2023第十届北京老年产业博览会/中国养老护理人才培育计划
CBIAIE北京老博会,打造2023年度唯具参展价值的老年行业盛会; 北京老博会:2011年,我国首场以“老年产业”为主题,一场专注于老年福祉、健康的国际型行业发展盛会,中国(北京)国际老年…...
网站底备案号链接代码/西安网站建设方案优化
操作系统原理作为计算机专业必学的一门基础专业课程,想必每个程序员都应该了解一下,今天我们就来说说几个基础的和操作系统相关的词汇。 内核 在学习操作系统原理的时候,很多书籍都会分处理器管理、存储器管理、文件管理及设备管理等等&#…...
网站开发怎么谈/seo超级外链工具免费
爬取网站时经常会遇到需要登录的问题,这是就需要用到模拟登录的相关方法。python提供了强大的url库,想做到这个并不难。这里以登录学校教务系统为例,做一个简单的例子。 首先得明白cookie的作用,cookie是某些网站为了辨别用户身份…...
wordpress读取其他数据库表/搜索引擎优化的方法
写代码经常会遇到socket要通过代理连接服务器的情况,代理类型通畅有三种:HTTP、SOCK4和SOCK5,通过学习和网上参考相关代码,写了个代理类来实现该功能,贴出来与大家共享 才贴出来两天,刚在百度一搜竟然发现已…...
临沂企业自助建站/外贸建站
图解TCP数据报结构以及三次握手(非常详细) TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的通信协议,数据在传输前要建立连接,传输完毕后还要断开连接…...
陕西 做网站的公司/win7优化工具哪个好用
GDI绘图基础 编写图形程序时需要使用GDI(图形设备接口Graphics Device Interface),从程序设计的角度看,GDI包括两个部分:GDI对象和GDI函数。 GDI对象定义了GDI函数使用的工具和环境变量,GDI函数对象绘制各…...
网站建设一般涉及后台功能/百度竞价投放
LeetCode 1005:K 次取反后最大化的数组和 (简单) 题目 描述 给定一个整数数组 A,我们只能用以下方法修改该数组:我们选择某个索引 i 并将 A[i] 替换为 -A[i],然后总共重复这个过程 K 次。(我们…...