Java 枚举 新特性

Java 枚举(enum)自JDK 1.5引入以来,随着版本的升级不断增强。本文将回顾枚举的演进,尤其是结合switch语句的应用,展示枚举如何在现代Java中变得更加灵活。
在这里插入图片描述


1. JDK 1.5:Java 枚举的诞生

在JDK 1.5之前,Java中没有直接支持枚举的机制。开发者通常会通过定义一系列static final常量来表示一组有限的值,例如表示一周的天数:

public class Day {public static final int MONDAY = 1;public static final int TUESDAY = 2;// 依此类推
}

这样的方式不仅不直观,而且容易出错。为了弥补这一点,Java在JDK 1.5中引入了enum关键字,允许开发者定义一个固定的常量集合:

public enum Day {MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
}

这不仅让代码更加简洁,也带来了类型安全。枚举值是Day类型,不再是简单的整型常量。


2. JDK 1.5:枚举的更多能力

除了基本的枚举值,enum类型还可以包含字段、方法和构造函数,这让枚举变得更加灵活。例如,你可以为每一天关联一个代表工作的小时数:

public enum Day {MONDAY(8), TUESDAY(8), WEDNESDAY(8), THURSDAY(8), FRIDAY(8), SATURDAY(0), SUNDAY(0);private int workHours;Day(int workHours) {this.workHours = workHours;}public int getWorkHours() {return workHours;}
}

这种设计让枚举不仅仅是常量的集合,还可以是具有行为的复杂对象


3. JDK 1.5:switch与枚举的结合

在JDK 1.5之前,switch语句仅支持int类型及其包装类、charString。随着enum的引入,Java允许我们在switch语句中使用枚举类型,这使得代码更加简洁和易读。

例子:

假设我们要根据一周中的某一天执行不同的操作,使用枚举结合switch语句可以显著简化逻辑代码:

public enum Day {MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
}public class Test {public static void main(String[] args) {Day day = Day.MONDAY;switch (day) {case MONDAY:System.out.println("Start of the work week");break;case FRIDAY:System.out.println("End of the work week");break;case SATURDAY: case SUNDAY:System.out.println("Weekend");break;default:System.out.println("Midweek");}}
}

上面的代码展示了如何在switch语句中使用枚举,不仅简化了逻辑,还确保了类型安全。我们再也不需要使用常量来控制switch,而是可以直接使用枚举的名称。


4. JDK 1.6:枚举与EnumSetEnumMap

在JDK 1.6 中,引入了两个重要的枚举相关工具类:EnumSetEnumMap

  • EnumSet:一个专门为枚举设计的高效Set实现,内部使用位向量来存储枚举值,因此比传统的HashSet更加高效。它特别适用于需要存储枚举类型的集合。

    EnumSet<Day> weekend = EnumSet.of(Day.SATURDAY, Day.SUNDAY);
    
  • EnumMap:与EnumSet类似,EnumMap是一种使用枚举类型作为键的高效Map实现。它内部使用数组来存储值,因此在内存和性能上有很大优势。

    EnumMap<Day, String> dayDescriptions = new EnumMap<>(Day.class);
    dayDescriptions.put(Day.MONDAY, "Start of the work week");
    

5. JDK 1.8:枚举与Stream API

JDK 1.8最重要的特性之一就是引入了Stream API,它极大地简化了对集合的操作。枚举也可以很方便地与Stream结合使用。例如,我们可以通过Stream对所有枚举值进行过滤和操作:

Arrays.stream(Day.values()).filter(day -> day.getWorkHours() > 0).forEach(System.out::println);

这种结合让枚举的使用更加灵活,并且能够与现代Java API无缝集成。


6. JDK 14:switch表达式和枚举

JDK 12引入预览版的switch表达式后,JDK 14正式将switch表达式作为语言特性之一。传统的switch语句是控制流语句,而**switch表达式**则可以直接返回值,使代码更加简洁、优雅。这一特性也可以与枚举结合使用。

例子:

假设我们需要根据一天的枚举类型来返回当天的描述。在JDK 14之前,代码可能看起来如下:

public String getDayDescription(Day day) {switch (day) {case MONDAY:return "Start of the work week";case FRIDAY:return "End of the work week";case SATURDAY:case SUNDAY:return "Weekend";default:return "Midweek";}
}

JDK 14之后,我们可以使用switch表达式,让代码更简洁:

public String getDayDescription(Day day) {return switch (day) {case MONDAY -> "Start of the work week";case FRIDAY -> "End of the work week";case SATURDAY, SUNDAY -> "Weekend";default -> "Midweek";};
}

switch表达式不仅让代码更加紧凑,还引入了箭头语法->),避免了冗余的break语句,减少了错误的可能性。


7. JDK 17:switchnull

在传统的switch语句中,传入null会导致NullPointerException,因此开发者必须在进入switch语句前显式检查null值。然而,在JDK 17中,Java开始支持在switch中直接处理null值。

在JDK 17之前,处理null的代码如下:

public String getDayDescription(Day day) {if (day == null) {return "Invalid day";}switch (day) {case MONDAY:return "Start of the work week";case FRIDAY:return "End of the work week";case SATURDAY:case SUNDAY:return "Weekend";default:return "Midweek";}
}

而在JDK 17中,我们可以在switch语句中直接处理null

public String getDayDescription(Day day) {return switch (day) {case null -> "Invalid day";case MONDAY -> "Start of the work week";case FRIDAY -> "End of the work week";case SATURDAY, SUNDAY -> "Weekend";default -> "Midweek";};
}

这种改进减少了代码中的冗余检查,并提高了程序的健壮性。


总结

随着JDK版本的迭代,Java的enum不仅在类型安全上更加强大,还与switch语句和表达式、Stream API等其他特性紧密结合。switch表达式和对null值的支持让枚举的使用更加灵活,开发者可以更简洁地处理各种逻辑,提高代码的可读性和可维护性。

通过合理使用这些特性,我们可以编写更清晰、高效的代码,将Java的强大特性充分发挥出来。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TAG:BladeLLM 的纯异步推理架构

作者&#xff1a;张子鹏 PAI引擎团队 随着 GQA/MLA/MoE 等模型结构不断发展&#xff0c;大语言模型的推理逐步解除了显存限制&#xff0c;逐渐向着高并发、高吞吐的方向发展。推理引擎的运行时开销也变得不可忽视。主流 LLM 推理框架的运行时开销大致来自&#xff1a; Python …

黑马十天精通MySQL知识点

一. MySQL概述 安装使用 MySQL安装完成之后&#xff0c;在系统启动时&#xff0c;会自动启动MySQL服务&#xff0c;无需手动启动。 也可以手动的通过指令启动停止&#xff0c;以管理员身份运行cmd&#xff0c;进入命令行执行如下指令&#xff1a; 1 、 net start mysql80…

Excel图片批量插入单元格排版处理插件【图片大师】

为了方便大家在图片的插入排版的重复工作中解放出来&#xff0c;最近发布了一款批量插入图片的插件&#xff0c;欢迎大家下载&#xff0c;免费试用。 这是图片的文件夹&#xff1a; 主要功能如下: 1&#xff0c;匹配单元格名称的多张图批量插入到一个单元格 该功能支持设置图…

学LabVIEW编程,看编程书有些看不懂怎么办?

自学LabVIEW编程时&#xff0c;如果发现编程书籍内容难以理解&#xff0c;可以尝试以下几种方式来提高学习效果&#xff1a; 1. 从基础入手&#xff0c;逐步深入&#xff1a; LabVIEW是一种基于图形化编程的工具&#xff0c;不同于传统的编程语言&#xff0c;因此从基础概念开…

尤雨溪推荐的拖拽插件,支持Vue2/Vue3 VueDraggablePlus

大家好,我是「前端实验室」爱分享的了不起~ 今天在网上看到尤雨溪推荐的这款拖拽组件,试了一下非常不错,这里推荐给大家。 说到拖拽工具库,非大名鼎鼎的的 Sortablejs 莫属。它是前端领域比较知名的,且功能强大的工具。但我们直接使用Sortablejs的情况很少,一般都是使用…

【Redis】之Geo

概述 Geo就是Geolocation的简写形式&#xff0c;代表地理坐标。在Redis中&#xff0c;构造了能够存储地址坐标信息的一种数据结构&#xff0c;帮助我们根据经纬度来检索数据。 命令行操作方法 GEOADD 可以用来添加一个或者多个地理坐标。 GEODIST 返回一个key中两个成员之…

【专题】2024跨境出海供应链洞察-更先进供应链报告合集PDF分享(附原数据表)

原文链接&#xff1a;https://tecdat.cn/?p37665 当前&#xff0c;全球化商业浪潮促使跨境电商行业飞速发展&#xff0c;产业带与跨境电商接轨、平台半托管模式涌现、社交电商带来红利机会以及海外仓不断扩张&#xff0c;这使得产业带外贸工厂、内贸工厂、传统进出口企业和品…

自制一键杀死端口进程程序# tomcat 如何杀死tomcat进程

直接cmd 窗口执行如下命令即可 netstat -ano | findstr :8080 taskkill /F /PID <PID>简简单单的两个指令,总是记不住,也懒的记, 每次端口冲突的时候, 都是直接查百度,很苦逼, 如果有一个程序,直接输入端口号,点击按钮直接杀死进程,岂不爽歪歪. 跟我一起制作一个屠猫的…

【D3.js in Action 3 精译_022】3.2 使用 D3 完成数据准备工作

当前内容所在位置 第一部分 D3.js 基础知识 第一章 D3.js 简介&#xff08;已完结&#xff09; 1.1 何为 D3.js&#xff1f;1.2 D3 生态系统——入门须知1.3 数据可视化最佳实践&#xff08;上&#xff09;1.3 数据可视化最佳实践&#xff08;下&#xff09;1.4 本章小结 第二章…

【网络原理】❤️Tcp 常用机制❤️ —— 延时应答,捎带应答, 面向字节流, 异常情况处理。保姆式详解 , 建议收藏 !!!

本篇会加入个人的所谓鱼式疯言 ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人…

[数据集][目标检测]无人机识别检测数据集VOC+YOLO格式6986张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;6986 标注数量(xml文件个数)&#xff1a;6986 标注数量(txt文件个数)&#xff1a;6986 标注…

‌内网穿透技术‌总结

内网穿透是一种网络技术&#xff0c;通过它可以使外部网络用户访问内部网络中的设备和服务。一般情况下&#xff0c;内网是无法直接访问的&#xff0c;因为它位于一个封闭的局域网中&#xff0c;无法从外部访问。而通过内网穿透&#xff0c;可以将内部网络中的设备和服务暴露在…

数据稀缺条件下的时间序列微分:符号回归(Symbolic Regression)方法介绍与Python示例

时间序列概况在日常生活和专业研究中都很常见。简而言之,时间序列概况是一系列连续的数据点 y(0), y(1), …, y(t) ,其中时间 t 的点依赖于时间 t-1 的前一个点(或更早的时间点)。 在许多应用中,研究者致力于预测时间序列概况的未来行为。存在各种建模方法。这些模型通常基于过…

Unity让摄像机跟随物体的方法(不借助父子关系)

在Unity中&#xff0c;不使用子对象的方式让相机跟随物体移动&#xff0c;我们通过编写脚本来实现。下面放一个从工程中摘出来的的C#脚本示例&#xff0c;用于将相机绑定到一个Target对象上并跟随其移动&#xff1a; using UnityEngine; public class FollowCamera : MonoBeh…

DPDK基础入门(十):虚拟化

I/O虚拟化 全虚拟化&#xff1a;宿主机截获客户机对I/O设备的访问请求&#xff0c;然后通过软件模拟真实的硬件。这种方式对客户机而言非常透明&#xff0c;无需考虑底层硬件的情况&#xff0c;不需要修改操作系统。 半虚拟化&#xff1a;通过前端驱动/后端驱动模拟实现I/O虚拟…

【STM32】CAN总线基础入门

CAN总线基础入门 一、CAN简介二、主流通信协议对比三、CAN物理层1、CAN硬件电路2、CAN电平标准3、CAN收发器 – TJA1050&#xff08;高速CAN&#xff09;4、CAN物理层特性 四、帧格式1、CAN总线帧格式2、数据帧&#xff13;、数据帧各部分用途简介&#xff14;、数据帧的发展历…

大模型参数高效微调技术原理综述(八)-MAM Adapter、UniPELT

MAM Adapter 背景 近年来提出了多种参数高效的迁移学习方法&#xff0c;这些方法仅微调少量&#xff08;额外&#xff09;参数即可获得强大的性能。虽然有效&#xff0c;但人们对为什么有效的关键要素以及各种高效微调方法之间的联系知之甚少。 下图展示了不同的微调方法&am…

小米,B站网络安全岗位笔试题目+答案

《网安面试指南》http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247484339&idx1&sn356300f169de74e7a778b04bfbbbd0ab&chksmc0e47aeff793f3f9a5f7abcfa57695e8944e52bca2de2c7a3eb1aecb3c1e6b9cb6abe509d51f&scene21#wechat_redirect 《Java代码审…

坚持的力量--完成向CSDN迁移500篇技术文章阶段小记-以此自勉

前言&#xff1a;本文为迁移前的博客中的文章《坚持的力量-写给第1000篇文章笔记》发表于 publish:May 14, 2021 -Friday&#xff0c;作为原个人博客中累计写满1000篇文章的总结和鼓励。因在向CSDN迁移文章的过程中进行了一些文章合并等调整&#xff0c;总文数大量下降&#xf…

ACM模式下算法题输入输出攻略【C++】

文章目录 [TOC] 1. 核心代码模式与ACM模式1.1 ACM模式介绍1.2 注意事项 2. C常用的输入输出方法2.1 输入2.1.1 cin注意事项2.1.2 getline()注意事项2.1.3 getchar()注意事项 2.2 输出 3. 案例3.1 一维数组输入3.1.1 固定长度的一维数组3.1.2 不固定长度的一维数组 3.2 二维数组…