【数据结构】(12) 反射、枚举、lambda 表达式
一、反射
1、反射机制定义及作用
反射是允许程序在运行时检查和操作类、方法、属性等的机制,能够动态地获取信息、调用方法等。换句话说,在编写程序时,不需要知道要操作的类的具体信息,而是在程序运行时获取和使用。
2、反射机制的原理
程序运行时,JVM会将编译好的 .class 文件(代表一个类)解析为 java.lang.Class 类的实例,这个实例包含了该类的所有信息。通过反射机制,可以用到这个实例,来获取该类的信息并进行操作。
下面介绍反射的相关类。以 Student 类为例子:
public class Student {//私有属性nameprivate String name = "小帅";//公有属性agepublic int age = 18;//不带参数的构造方法public Student(){System.out.println("Student()");}private Student(String name,int age) {this.name = name;this.age = age;System.out.println("Student(String,name)");}private void eat(){System.out.println("i am eat");}public void sleep(){System.out.println("i am pig");}private void function(String str) {System.out.println(str);}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}
}
Class 在 java.lang 中,不需要导包。其它三个都在 java.lang.reflect 中。
3、Class 类
代表类的实体。
获取 JVM 给类解析的 Class 对象:

其它方法:

4、Field 类
代表类的属性。
- getField(String name):获得指定公有属性对象。
- getField():获得所有公有属性对象。
- getDeclaredField(String name):获得某个属性对象。(不限于公有)
- getDeclaredField():获得所有属性对象。

属性对象.get(对象) 表示获取指定对象的某属性,静态属性不需对象,参数填 null。
5、Method 类
代表类的方法。


6、Constructor 类
代表类的构造方法。

利用构造方法对象获得类的实例:
‘
7、使用反射动态加载类并创建对象
编写一个程序,在运行时根据用户输入的类名来动态加载类并创建对象,调用其 draw 方法。
import java.util.Scanner;// 定义一个 Shape 接口
interface Shape {void draw();
}// 定义 Circle 类实现 Shape 接口
class Circle implements Shape {@Overridepublic void draw() {System.out.println("绘制一个圆形");}
}// 定义 Rectangle 类实现 Shape 接口
class Rectangle implements Shape {@Overridepublic void draw() {System.out.println("绘制一个矩形");}
}public class DynamicClassLoadingExample {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);System.out.println("请输入要加载的类名(如 Circle 或 Rectangle):");String className = scanner.nextLine();try {// 根据用户输入的类名获取 Class 对象Class<?> clazz = Class.forName(className);// 创建该类的实例Shape shape = (Shape) clazz.getDeclaredConstructor().newInstance();// 调用 draw 方法shape.draw();} catch (Exception e) {e.printStackTrace();}scanner.close();}
}
反射优点:让程序更灵活,动态加载类和方法、可以访问和修改私有成员。
反射缺点:性能开销大、破坏封装性和安全性、程序不易读。
二、枚举
1、定义及作用
一组常量,比如颜色,它们是同一类,我们想把这组常量组织在一起,就用枚举。作用是与没有意义的数字区分开来(如果定义一组常量,就要用数字表示它们)。例子:
public enum Color {RED, GREEN, BLUE;public static void main(String[] args) {Color color = Color.BLUE;switch (color) {case RED:System.out.println("RED");break;case GREEN:System.out.println("GREEN");break;case BLUE:System.out.println("BLUE");break;default:System.out.println("default");break;}}
}
枚举类默认继承了 java.lang.Enum。枚举常量的默认是 public static final 修饰。
2、常用方法

枚举类型能够使用这些方法,是因为默认继承了 Enum 类:

但是可以发现,Enum 类中没有 values 方法。这是因为自定义枚举类型中枚举常量的数量、类型都是不确定的,如果 values 封装在 Enum 类中,就需要在运行时动态确定每个枚举常量(需要用到反射,破坏了封装性、增强了复杂性等)。实际上,编译器编译时会为每个枚举类型自动加上 values 方法,返回的数组在编译时就确定。
3、构造方法
枚举相当于是类,可以有属性、构造方法、方法。构造方法默认私有,且只能。这样保证了枚举实例的唯一性。

查看构造函数的实际参数有哪些:

多了 String 和 int 类型参数,因为枚举类默认继承了 Enum,其本身有 name 和 ordinal 属性,隐藏了 super(name, ordinal) ,所以 Color 构造函数会多 2 个参数。


4、枚举和反射
通过反射获取枚举类的实例:

出现错误:

查看 newInstance 源码:

因此,不能通过反射创建枚举类的实例。这样设计的目的是让枚举类只有一个实例,防止反射攻击。由私有构造函数、防反射攻击这两个特点得知,枚举实现单例模式(一种创建型模式,它确保一个类只有一个实例,并提供一个全局访问点来获取这个实例)是安全的。
枚举优点:简单安全。
枚举缺点:不能继承。
5、枚举实现单例模式
后续学了单例模式补充。
三、Lambda 表达式
1、定义及作用
相当于方法,但是比方法更简化。语法:
(形参列表)->表达式(形参列表)->{代码块}// 参数类型可以省略(要省全都省),只有一个参数可以省略圆括号。// 返回一个值或者不返回值// 只有一条 return 语句,可省略 return
2、函数式接口
- 函数式接口:一个接口只有一个抽象方法。
- @FunctionalInterface 注解:以函数式接口的标准(只有一个抽象方法)要求接口,检查作用。
- lambda 可简化匿名内部,实现函数式接口。

几个函数式接口代码:
//无返回值无参数
@FunctionalInterface
interface NoParameterNoReturn {void test();
}
使用匿名内部类实现接口,重写方法:

使用 lambda 实现接口,重写方法:
NoParameterNoReturn noParameterNoReturn = ()->{System.out.println("hello");};
3、变量捕获
匿名内部类中可捕获外部变量。如果想修改捕获的变量,那该变量必须被 final 修饰,否则报错。lambda 表达式同理。
int a = 10;PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {
// a = 99; 不允许修改未被 final 修饰的外部变量System.out.println(a); // 变量 a 捕获return o1.compareTo(o2);}});

4、Lambda 在集合中的应用

lambda 表达式作为以上方法的参数,实现接口中的方法。
4.1、Collection 接口
以 forEach 为例:
源码如下:Consumer 是函数式接口,accept 是实现的抽象方法。


实现函数式接口:

4.2、List 接口
以 sort 为例:
源码:

在 Java 中,所有类都直接或间接地继承自 Object 类,因此,Comparator 接口继承了 Object 类的 equals 方法。它不是 Comparator 接口自身定义的抽象方法,因此,不违反函数式接口的定义规则。
@FunctionalInterfacepublic interface Comparator<T> {int compare(T o1, T o2);boolean equals(Object obj); // 继承自 Object,不影响函数式接口......}
实现:

4.3、Map 接口
以 forEach 为例:
源码:


实现:

5、总结:
优点:语句简洁、方便函数式编程(替换匿名内部类)、改善集合操作。
缺点:可读性差、不易调试。
相关文章:
【数据结构】(12) 反射、枚举、lambda 表达式
一、反射 1、反射机制定义及作用 反射是允许程序在运行时检查和操作类、方法、属性等的机制,能够动态地获取信息、调用方法等。换句话说,在编写程序时,不需要知道要操作的类的具体信息,而是在程序运行时获取和使用。 2、反射机制…...
SEO炼金术(4)| Next.js SEO 全攻略
在上一篇文章 SEO炼金术(3)| 深入解析 SEO 关键要素 中,我们深入解析了 SEO 关键要素,包括 meta 标签、robots.txt、canonical、sitemap.xml 和 hreflang,并探讨了它们在搜索引擎优化(SEO)中的作…...
ONES 功能上新|ONES Copilot、ONES Project 新功能一览
ONES Copilot 智能 AI 助手模型可配置多种类型模型,服务提供方 Dashscope 的模型列表中新增 DeepSeek V3 与 DeepSeek R1;选择自定义模型配置时,填写私有部署的 DeepSeek 模型相关参数即可。 应用场景: 企业内部自部署或在模型服务…...
STM32寄存器控制引脚高低电平
一. 引子 最近在学习32代码的过程当中,虽然在学习IMX6ULL开发板的过程中接触过很多寄存器,最近在返回去看32的时候,在研究代码的时候发现自己对于寄存器的有些特性理解的不够深刻,所以下来的时候去查了资料,以及问了一…...
SOC-ATF 安全启动BL1流程分析(1)
一、ATF 源码下载链接 1. ARM Trusted Firmware (ATF) 官方 GitHub 仓库 GitHub 地址: https://github.com/ARM-software/arm-trusted-firmware 这是 ATF 的官方源码仓库,包含最新的代码、文档和示例。 下载方式: 使用 Git 克隆仓库: git…...
QVariantList使用详解
QVariantList 1. 基本概念2. 使用场景3. 基本操作3.1 创建和初始化3.2 访问元素3.3 修改元素3.4 删除元素 4. 实际应用示例5. 总结其他QT文章推荐 QVariantList 是 Qt 框架中的一个类,用于存储和操作 QVariant 对象的列表。 QVariant 是 Qt 中用于封装各种类型的通…...
TDesign:Cascader 级联选择器(省市区三级联动)
Cascader 级联选择器API 参考官方示例代码 在自己的模板中使用:view import package:ducafe_ui_core/ducafe_ui_core.dart; import package:flutter/material.dart; import package:get/get.dart; import package:tdesign_flutter/tdesign_flutter.dart;import i…...
Ubuntu20.04下各类常用软件及库安装汇总
1.Miniconda的安装 Ubuntu 20.04版本快速安装 Miniconda(宝宝级攻略) 2.Nvidia显卡驱动/CUDA/cuDNN安装 Ubuntu 20.04安装nvidia显卡驱动/CUDA/cuDNN Ubuntu 20.04:CUDAcuDNN安装&卸载 Y9000P24款 win11ubuntu20.04 双系统教程 3.SGL…...
linux中安装部署Jenkins,成功构建springboot项目详细教程
参考别人配置Jenkins的git地址为https,无法连上github拉取项目,所以本章节介绍通过配置SSH地址来连github拉取项目 目录: 1、springboot项目 1.1 创建名为springcloudproject的springboot项目工程 1.2 已将工程上传到github中,g…...
2025系统架构师(一考就过):案例之四:架构复用、架构评估、特定架构(DSSA)、架构开发方法(ABSD)
二、软件架构复用 ◆软件产品线是指一组软件密集型系统,它们共享一个公共的、可管理的特性集,满足某个特定市场或任务的具体需要,是以规定的方式用公共的核心资产集成开发出来的。即围绕核心资产库进行管理复用、集成新的系统。 ◆软件架构…...
基于定制开发开源AI大模型S2B2C商城小程序的商品选品策略研究
摘要:随着电子商务的蓬勃发展和技术的不断进步,商品选品在电商领域中的重要性日益凸显。特别是在定制开发开源AI大模型S2B2C商城小程序的环境下,如何精准、高效地选择推广商品,成为商家面临的一大挑战。本文首先分析了商品选品的基…...
后端之JPA(EntityGraph+JsonView)
不同表之间的级联操作或者说关联查询是很多业务场景都会用到的。 对于这种需求最朴素的方法自然是手动写关联表,然后对被关联的表也是手动插入数据。但是手写容易最后写成一堆shit代码,而且修改起来也是非常麻烦的。 学会使用现成的工具还是非常有利的…...
linux--卡顿
1,swappiness swappiness是一个影响操作系统如何使用交换空间(swap space)的内核参数。它的值范围是从0到100,这个数值决定了系统将数据从物理内存(RAM)移动到交换分区或交换文件的倾向程度,交…...
【Python pro】函数
1、函数的定义及调用 1.1 为什么需要函数 提高代码复用性——封装将复杂问题分而治之——模块化利于代码的维护和管理 1.1.1 顺序式 n 5 res 1 for i in range(1, n1):res * i print(res) # 输出:1201.1.2 抽象成函数 def factorial(n):res 1for i in range(1…...
Docker 2025/2/24
用来快速构建、运行和管理应用的工具。帮助部署。 快速入门 代码略 解释 docker run :创建并运行一个容器,-d是让容器在后台运行 --name mysql :给容器起个名字,必须唯一 -p 3306:3306 :设置端口映射 -e KEYVALUE :是设置环境变量 mysql :指定运行的…...
4. 示例:创建带约束的随机地址生成器(范围0x1000-0xFFFF)
文章目录 前言代码示例:运行方法:查看结果:关键功能说明:扩展功能建议: 前言 以下是一个完整的SystemVerilog测试平台示例,包含约束随机地址生成、日志输出和波形生成功能: 代码示例࿱…...
爱普生SG-8101CE可编程晶振赋能智能手机的精准心脏
在智能手机高速迭代的今天,高性能、低功耗与小型化已成为核心诉求。智能手机作为人们生活中不可或缺的工具,需要在各种复杂场景下稳定运行。爱普生SG-8101CE可编程晶振凭借其卓越性能,成为智能手机中不可或缺的精密时钟源,为通信、…...
指针解剖学:穿透C/C++内存操作的核心密码与避坑指南
一、指针的本质与内存模型 指针是C/C的核心特性,本质是内存地址的变量化表示。每个变量在内存中占据连续的字节空间,地址是内存单元的唯一编号(如0x0028FF40)。指针变量存储的是目标数据的首地址,通过地址间接操作数据…...
Qt关于平滑滚动的使用QScroller及QScrollerProperties类说明
一、触控时代的滚动工具:QScroller类设计介绍 1.1 从机械滚轮到数字惯性 在触控设备普及前,滚动操作如同老式打字机的滚轴,只能通过鼠标滚轮或滚动条进行离散式控制。QScroller的出现如同给数字界面装上了"惯性飞轮",…...
【音视频】编解码相关概念总结
NALU RTP PS流 三者总体关系 NALU在RTP中的应用:视频流的RTP传输通常将NALU作为基本的单元进行传输。每个RTP包携带一个或多个NALU,这些NALU包含了视频编码数据。RTP协议通过其头部信息(如时间戳、序列号等)帮助接收端重新排列和…...
Vue3 + Vite + TS,使用 配置项目别名属性:resolve
使用 resolve 配置全局项目路径别名 1.优化了开发中单页面引用其他模块的路径复杂性 2.妥妥解决了,组件复用当中提高开发效率 // 不使用配置 import { useStore } from ../../../stores // 使用配置 可根据开发者需求任意定义,较多 import { useStore…...
docker创建nginx
docker run -d -p 8080:80 --name my-nginx-container nginx docker:命令 run:命令 -d:在后台运行容器 -p:8080:80:将容器内部的80端口映射到宿主机的8080端口。 --name my-nginx-container:为容器指定一个…...
StableDiffusion打包 项目迁移 项目分发 1
文章目录 SD项目迁移前置知识webui-user.batwebui.batlaunch_utils.py 下一篇开始实践 SD项目迁移 显卡驱动更新:https://www.nvidia.cn/geforce/drivers/ 下载安装三个程序: python3.10.6: https://www.python.org/downloads/release/python-3106/gi…...
【数据结构进阶】哈希表
🌟🌟作者主页:ephemerals__ 🌟🌟所属专栏:数据结构 目录 前言 一、哈希表的概念 二、哈希函数的实现方法 1. 直接定址法 2. 除留余数法 三、哈希冲突 1. 开放定址法(闭散列࿰…...
【蓝桥杯嵌入式】各模块学习总结
系列文章目录 留空 文章目录 系列文章目录前言一、LED模块1.1 赛题要求1.2 模块原理图1.3 编写代码1.4 赛题实战 二、LCD模块2.1 赛题要求2.2 模块原理图2.3 编写代码2.4 赛题实战 三、按键模块3.1 赛题要求3.2 模块原理图3.3 编写代码3.4 赛题实战 四、串口模块4.1 赛题要求4…...
Rust学习总结之-枚举
枚举是一个很多语言都有的功能,不过不同语言中其功能各不相同但是要表达的意思是一致的,枚举就是对于一个事物可以穷举出所有可能得值。比如说人的性别就可以用枚举,男人和女人两种。下面我们来学习Rust中的枚举。 一:枚举定义 …...
Linux系统管理(十七)——配置英伟达驱动、Cuda、cudnn、Conda、Pytorch、Pycharm等Python深度学习环境
文章目录 前言安装驱动下载安装Cuda编辑环境变量安装Cudnn安装conda验证安装成功配置conda镜像退出conda环境创建python环境查看当前conda环境激活环境安装python包安装pytorch 安装pycharm安装jupyter notebook 前言 深度学习和大语言模型的部署不免会用到Linux系统ÿ…...
SLAM算法工程师的技术图谱和学习路径
SLAM(Simultaneous Localization and Mapping)算法工程师是负责开发和实现用于机器人、自动驾驶车辆等领域的SLAM算法的专业人士。下面是SLAM算法工程师需要掌握的基础理论知识: 机器人运动学和动力学:理解机器人在空间中的运动方式和控制方法,包括轮式、蜘蛛腿、飞行器等…...
【第三天】零基础学习量化基础代码分析-持续更新
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 记录量化基础代码总览引言基本概念量化投资 伪代码示例:量化投资模型框架总结 每日-往期回看 第一天零基础学量化基础知识点总览-持续更新 第二天零基础…...
深入了解 Python 中的 MRO(方法解析顺序)
文章目录 深入了解 Python 中的 MRO(方法解析顺序)什么是 MRO?如何计算 MRO?C3 算法的合并规则C3 算法的合并步骤示例:合并过程解析 MRO 解析失败的场景使用 mro() 方法查看 MRO示例 1:基本用法 菱形继承与…...
