【数据结构】(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、反射机制…...
java实现二维码图片生成和编解码
java实现二维码图片生成和编解码 在wutool中,封装了二维码工具类,基于google的zxing库,实现二维码图片生成、编码和解码。 关于wutool wutool是一个java代码片段收集库,针对特定场景提供轻量解决方案,只要按需选择代…...
Java基础常见的面试题(易错!!)
面试题一:为什么 Java 不支持多继承 Java 不支持多继承主要是为避免 “菱形继承问题”(又称 “钻石问题”),即一个子类从多个父类继承到同名方法或属性时,编译器无法确定该调用哪个父类的成员。同时,多继承…...
hugging face---transformers包
一、前言 不同于计算机视觉的百花齐放,不同网络适用不同情况,NLP则由Transformer一统天下。transformer是2017年提出的一种基于自注意力机制的神经网络架构,transformers库是hugging face社区创造的一个py库,通过该库可以实现统一…...
网络安全防护指南:筑牢网络安全防线(510)
一、网络安全的基本概念 (一)网络的定义 网络是指由计算机或者其他信息终端及相关设备组成的按照一定的规则和程序对信息收集、存储、传输、交换、处理的系统。在当今数字化时代,网络已经成为人们生活和工作中不可或缺的一部分。它连接了世…...
微信小程序实现拉卡拉支付
功能需求:拉卡拉支付(通过跳转拉卡拉平台进行支付),他人支付(通过链接进行平台跳转支付) 1.支付操作 //支付 const onCanStartPay async (obj) > {uni.showLoading({mask: true})// 支付接口获取需要传…...
git从本地其他设备上fetch分支
在 Git 中,如果你想从本地其他设备上获取分支,可以通过以下几种方式实现。不过,需要注意的是,Git 本身是分布式版本控制系统,通常我们是从远程仓库(如 GitHub、GitLab 等)拉取分支,而…...
【干货教程】Windows电脑本地部署运行DeepSeek R1大模型(基于Ollama和Chatbox)
文章目录 一、环境准备二、安装Ollama2.1 访问Ollama官方网站2.2 下载适用于Windows的安装包2.3 安装Ollama安装包2.4 指定Ollama安装目录2.5 指定Ollama的大模型的存储目录 三、选择DeepSeek R1模型四、下载并运行DeepSeek R1模型五、常见问题解答六、使用Chatbox进行交互6.1 …...
基于 SSM框架 的 “捷邻小程序” 系统的设计与实现
大家好,今天要和大家聊的是一款基于 SSM框架 的 “捷邻小程序” 系统的设计与实现。项目源码以及部署相关事宜请联系我,文末附上联系方式。 项目简介 基于 SSM框架 的 “捷邻小程序” 系统设计与实现的主要使用者分为 管理员 和 用户,没有授…...
基于Springboot医院预约挂号小程序系统【附源码】
基于Springboot医院预约挂号小程序系统 效果如下: 小程序主页面 帖子页面 医生账号页面 留言内容页面 管理员主页面 用户管理页面 我的挂号页面 医生管理页面 研究背景 随着信息技术的飞速发展和互联网医疗的兴起,传统的医疗服务模式正面临着深刻的变…...
基于AVue的二次封装:快速构建后台管理系统的CRUD方案
基于AVue的二次封装:快速构建后台管理系统的CRUD方案 在开发后台管理系统时,表格是常见的组件之一。然而,使用原生的Element Plus实现CRUD(增删改查)功能往往需要编写大量重复代码,过程繁琐。即使借助类似…...
【含开题报告+文档+PPT+源码】基于springboot加vue 前后端分离的校园新闻审核发布管理系统
开题报告 本研究旨在设计并实现一套基于SpringBoot后端框架结合Vue前端技术的校园新闻发布系统,该系统面向学生用户群体提供了全面的功能服务。学生用户通过身份验证登录后,能够便捷高效地获取校园内的各类新闻资讯,实时了解校内动态。系统不…...
Qt 是一个跨平台的 C++ 应用程序框架
Qt 是一个跨平台的 C++ 应用程序框架,广泛用于开发图形用户界面(GUI)应用程序,也可以用于开发非 GUI 程序,如命令行工具和控制台应用程序。Qt 提供了丰富的类库和工具,支持多种操作系统,包括 Windows、macOS、Linux 等。 主要特点: 跨平台:Qt 支持多种操作系统,开发…...
2025年SCI一区智能优化算法:真菌生长优化算法(Fungal Growth Optimizer,FGO),提供MATLAB代码
一. 真菌生长优化算法(FGO) 真菌生长优化算法(Fungal Growth Optimizer,FGO)是一种新型的自然启发式元启发式算法,其灵感来源于自然界中真菌的生长行为。该算法通过模拟真菌的菌丝尖端生长、分支和孢子萌发…...
解决Spring Boot中Druid连接池“discard long time none received connection“警告
在使用Spring Boot结合Druid连接池时,开发者可能会遇到"discard long time none received connection"的警告信息。虽然这通常不会影响应用程序的正常运行,但这些警告信息可能会让人感到困扰。本文将探讨这个问题的原因,并提供几种…...
stm32常见的存储器应用
常用 STM32 存储器芯片介绍和应用 STM32 微控制器通常与多种存储器芯片一起工作,以下是几种常见的存储器类型及其应用: 1. 闪存(Flash Memory) STM32 内部的 闪存 是一种非易失性存储器,广泛用于存储程序代码和常驻…...
如何使用3D高斯分布进行环境建模
使用3D高斯分布来实现建模,主要是通过高斯分布的概率特性来描述空间中每个点的几何位置和不确定性。具体来说,3D高斯分布被用来表示点云数据中的每一个点或体素(voxel)的空间分布和不确定性,而不是单纯地存储每个点的坐…...
三级分类bug解决
文章目录 前端后端 前端 <!DOCTYPE html> <html xmlns:th"http://www.thymeleaf.org" lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0&q…...
AxiosError: Network Error
不知怎么的,项目还在开发阶段,之前还好好的,玩儿了两天再一打开发现页面无法显示数据了,报错如下: 我以为是后端出问题了,但是后端控制台无报错,又用postman测试了一下,可以获取到数…...
CDefFolderMenu_MergeMenu函数分析之添加了分割线和属性菜单项两项
CDefFolderMenu_MergeMenu函数分析之添加了分割线和属性菜单项两项 第一部分: void CDefFolderMenu_MergeMenu(HINSTANCE hinst, UINT idMainMerge, UINT idPopupMerge, QCMINFO *pqcm) { UINT idMax pqcm->idCmdFirst; if (idMainMerge) { HME…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...
Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...
Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...
【C++进阶篇】智能指针
C内存管理终极指南:智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...
Golang——6、指针和结构体
指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...
tomcat指定使用的jdk版本
说明 有时候需要对tomcat配置指定的jdk版本号,此时,我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...
