Java枚举详解

一、什么是枚举类型

        枚举类型是一种特殊的数据类型,用于定义一组固定的命名常量。枚举类型提供了一种更强大、更安全和更易读的方式来表示一组相关的常量。

        在Java中,枚举类型是通过使用enum关键字来定义的。枚举类型可以包含一个或多个枚举常量,每个常量都是枚举类型的实例。枚举常量是在枚举类型中预先定义的,它们是唯一的、已命名的对象。

        在Java中,枚举类型是一组固定常量值的集合,每个常量值代表一个特定的数据类型。枚举在Java中被视为数据类型,你可以使用它们来创建枚举类型的变量、数组、参数等。

二、枚举的引入

要求创建一个季节(Season)类,只能创建春夏秋冬4个对象。

  • 旧方法:假如按照以往的思路,只能创建一个普通的Season 类。
  • 代码如下:

public class Enumeration01 {public static void main(String[] args) {//使用Season spring = new Season("春天", "温暖");Season winter = new Season("冬天", "寒冷");Season summer = new Season("夏天", "炎热");Season autumn = new Season("秋天", "凉爽");Season other = new Season("红天", "~~~");// 可以随意多创建对象,不满足题目要求
//     autumn.setName("XXX");// 会改变对象的属性,不满足题目的要求
//     autumn.setDesc("非常的热..");}
}
class Season{//类private String name;private String desc;// 季节描述public Season(String name, String desc) {this.name = name;this.desc = desc;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getDesc() {return desc;}public void setDesc(String desc) {this.desc = desc;}
}

        思考:使用普通类的定义,我们不能体现Season 类只有4个固定的对象,因为使用者可以随意创建更多的对象。因此我们需要一种特殊的类,可以限制使用者创建的对象的个数与类型 ---- 于是便引入了枚举类。
        枚举(enumeration):枚举是一组常量的集合;它是一种特殊的类,里面只包含一组有限的特殊的不能修改的对象。

三、枚举的基本用法

  • 使用 enum 关键字实现枚举:

使用步骤:
(1)使用 enum 关键字取代 class 关键字定义一个类,该类便称为枚举类。
(2)在枚举类内部直接创建对象,枚举类对象是默认使用 public static final 一起修饰的,如果有多个对象,则必须且只能使用(,)间隔开。
(3)在枚举类中将构造器私有化,防止外部随意创建枚举类对象。
(4)只保留属性的get 方法,不提供属性的 set 方法,防止枚举类的对象属性被更改。

  • 将上例代码修改如下:

public class Enumeration03 {public static void main(String[] args) {System.out.println(Season.AUTUMN);System.out.println(Season.SUMMER);}
}enum  Season {//类//定义了四个静态对象,使用了enum 来实现枚举类/*1. 使用关键字 enum 替代 class;2. public static final Season SPRING = new Season("春天", "温暖") 直接使用SPRING("春天", "温暖") 来代替,即常量名(实参列表);3. 如果有多个常量(对象), 使用 , 号间隔即可;4. 如果使用enum 来实现枚举,要求将定义常量对象的语句,写在第一行;5. 如果我们使用的是无参构造器,创建常量对象,则可以省略括号();*/SPRING("春天", "温暖"), WINTER("冬天", "寒冷"), AUTUMN("秋天", "凉爽"),SUMMER("夏天", "炎热");// 调用了构造器// 下面定义对象的语句和上面的效果是一样的。
//    public static final Season SPRING = new Season("春天", "温暖");
//    public static final Season WINTER = new Season("冬天", "寒冷");
//    public static final Season AUTUMN = new Season("秋天", "凉爽");
//    public static final Season SUMMER = new Season("夏天", "炎热");private String name;private String desc;private Season() {//无参构造器}private Season(String name, String desc) {this.name = name;this.desc = desc;}public String getName() {return name;}public String getDesc() {return desc;}// 打印对象的信息@Overridepublic String toString() {return "Season{" +"name='" + name + '\'' +", desc='" + desc + '\'' +'}';}
}
  • 说明:使用 enum 关键字后,Season 类中的对象变成了固定的对象,这样便能满足我们一开始提出的要求了。
  • 对比图如下:

四、枚举的注意事项和细节 

(1)当我们使用 enum 关键字开发一个枚举类时,默认会继承 Enum 类,而且是一个 final 类,不能再被其他类继承。
(2)传统的 public static final Season2 SPRING = new Season2(“春天”, “温暖”); 简化成 SPRING(“春天”, “温暖”), 这里必 须知道,它调用的是哪个构造器。
(3)如果使用无参构造器 创建 枚举对象时,其实参列表和小括号都可以省略。
(4)当有多个枚举对象时,使用(,)间隔,最后由一个分号结尾。
(5)定义类枚举对象的语句必须放在枚举类的第一句。

(6)使用 enum 关键字后,就不能再继承其它类了,因为 enum 类会隐式继承 Enum,而 Java 是单继承机制。

五、枚举类的常用方法

以下是枚举类型常用的方法以及它们的用途:

  • 代码演示:
public class EnumMethod {public static void main(String[] args) {//使用Season 枚举类,来演示各种方法Season autumn = Season.AUTUMN;//输出枚举对象的名字  AUTUMNSystem.out.println(autumn.name());//ordinal() 输出的是该枚举对象的次序/位置号,从0开始编号//AUTUMN 枚举对象是第三个,因此输出 2System.out.println(autumn.ordinal());// values方法,返回 Season2[]// 含有定义的所有枚举对象Season[] values = Season.values();System.out.println("===遍历取出枚举对象(增强for)====");for (Season season: values) {System.out.println(season);}//valueOf:将字符串转换成枚举对象,要求字符串必为已有的对象名,否则报异常//执行流程//1. 根据你输入的 "AUTUMN" 到 Season2的枚举对象去查找//2. 如果找到了,就返回,如果没有找到,就报错Season autumn1 = Season.valueOf("AUTUMN");System.out.println("autumn1=" + autumn1);System.out.println(autumn == autumn1);//compareTo:比较两个枚举常量,比较的就是位置号// 就是把 Season.AUTUMN 枚举对象的位置号 和 Season.SUMMER枚举对象的位置号比较/*源码如下:public final int compareTo(E o) {return self.ordinal - other.ordinal;}*/// Season.AUTUMN的编号[2] - Season.SUMMER的编号[3]System.out.println(Season.AUTUMN.compareTo(Season.SUMMER));// 最后补充了一个增强forint[] nums = {1, 2, 9};//普通的for循环System.out.println("=====普通的for=====");for (int i = 0; i < nums.length; i++) {System.out.println(nums[i]);}System.out.println("=====增强的for=====");//执行流程是 依次从nums数组中取出数据,赋给i, 如果取出完毕,则退出forfor(int i : nums) {System.out.println("i=" + i);}}
}

六、枚举的优缺点

优点:

1.易读性和可维护性:枚举类型中的常量是有意义的、自描述的,使得代码更易读、易理解和易于维护。枚举常量具有唯一的名称,提供了更好的文档和注释。

2.类型安全:枚举类型在编译时进行静态类型检查,这意味着编译器可以确保只使用有效的枚举常量,提供了更高的类型安全性。

3.可限定的值集合:枚举类型定义了一个有限的值集合,限定了有效的取值范围。这可以帮助避免程序中出现无效或意外的取值。

4.避免魔法数值:使用枚举类型可以避免使用硬编码的魔法数值,提供了更好的代码可读性和可维护性。

5.增强的编译器支持:枚举类型在编译器层面提供了一些额外的支持,如自动添加常用方法(如values()、valueOf())、枚举常量的顺序等。

6.适用于状态和选项的表示:枚举类型非常适用于表示状态、选项和固定集合,如季节、颜色、星期几等。
 

缺点:

1.不适用于动态变化的数据:枚举类型是在编译时定义的,其常量集合是固定的。如果需要表示动态变化的数据集合,枚举类型可能不适合。

2.不适用于大型数据集合:如果需要表示大型的数据集合,枚举类型的常量定义可能会变得冗长和繁琐。

3.缺乏扩展性:枚举类型的常量是在编译时确定的,不支持动态添加或删除常量。因此,如果需要频繁地修改常量集合,可能会导致代码的改动和维护成本的增加。

4.不支持继承:枚举类型不支持继承,无法实现枚举类型之间的继承关系。
 

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

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

相关文章

DELL MD3600F存储重置管理软件密码

注意&#xff1a;密码清除可能会导致业务秒断&#xff0c;建议非业务时间操作 针对一台控制器操作即可&#xff0c;另一控制器会同步操作 重置后密码为空&#xff01; 需求&#xff1a;重置存储管理软件密码 管理软件中分配物理磁盘时提示输入密码(类似是否了解风险确认操作的提…

【网易云商】构建高效 SaaS 系统的技术要点与最佳实践

SaaS 是什么 定义 相信大家都对云服务中的 IaaS、PaaS、SaaS 早就有所耳闻&#xff0c;现在更是衍生出了 aPaaS、iPaaS、DaaS 等等的类似概念。对于 SaaS 也有各种各样的定义&#xff0c;本文给出的定义是&#xff1a; SaaS 是一种基于互联网提供服务和软件的交付模式&#xf…

Wireshark的捕获过滤器

Wireshark的过滤器&#xff0c;顾名思义&#xff0c;作用是对数据包进行过滤处理。具体过滤器包括捕获过滤器和显示过滤器。本文对捕获过滤器进行分析。 捕获过滤器&#xff1a;当进行数据包捕获时&#xff0c;只有那些满足给定的包含/排除表达式的数据包会被捕获。 捕获过滤器…

什么是轻量应用服务器?可以从亚马逊云科技的优势入手了解

什么是轻量应用服务器&#xff1f; 随着如今各行各业对云计算的需求越来越多&#xff0c;云服务器也被越来越多的企业所广泛采用。其中&#xff0c;轻量应用服务器是一种简单、高效、可靠的云计算服务&#xff0c;能够为开发人员、企业和个人提供轻量级的虚拟专用服务器&#x…

MeterSphere | 接口测试请求体中,int类型的入参实现动态化变量

项目场景&#xff1a; 在接口自动化的时候&#xff0c;要把上一个接口的 Int 变量传入到 下一个接口中进行使用&#xff0c;但编译器会出现 红色的 X 符号 问题描述 如何实现 int 类型的入参实现动态化变量&#xff1f; 解决方案&#xff1a; 忽视掉这个红色 X 号&#xff0…

使用 JavaScript 进行 API 测试的综合教程

说明 API 测试是软件测试的一种形式&#xff0c;涉及直接测试 API 并作为集成测试的一部分&#xff0c;以确定它们是否满足功能、可靠性、性能和安全性的预期。 先决条件&#xff1a; JavaScript 基础知识。Node.js 安装在您的计算机上。如果没有&#xff0c;请在此处下载。npm…

深度学习之基于Tensorflow银行卡号码识别系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介银行卡号码识别的步骤TensorFlow的优势 二、功能三、系统四. 总结 一项目简介 # 深度学习基于TensorFlow的银行卡号码识别介绍 深度学习在图像识别领域取得…

【libGDX】Mesh纹理贴图

1 前言 纹理贴图的本质是将图片的纹理坐标与模型的顶点坐标建立一一映射关系。纹理坐标的 x、y 轴正方向分别朝右和朝下&#xff0c;如下。 2 纹理贴图 本节将使用 Mesh、ShaderProgram、Shader 实现纹理贴图&#xff0c;OpenGL ES 的实现见博客 → 纹理贴图。 DesktopLauncher…

K8S客户端一 Rancher的安装

一 安装方式一 通过官网方式安装&#xff1a;官网 sudo docker run --privileged -d --restartunless-stopped -p 80:80 -p 443:443 rancher/rancher:stable访问服务器地址即可&#xff1a;http://192.168.52.128 修改语言 第一次安装会生成密码&#xff0c;查看密码步骤如下…

LeetCode Hot100 102.二叉树的层序遍历

题目&#xff1a; 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 方法&#xff1a;迭代 class Solution {public List<List<Integer>> levelOrder(TreeNode root) {if …

OPPO VOOC快充原理

1 USB 3.0标准A插头 USB 3.0连接器是基于USB 2.0改进而来的&#xff0c;这个设计给USB 3.0连接器带来了一些潜在风险&#xff0c;如果USB 3.0设备插入主机的速度太慢&#xff0c;3.0的针脚还没来得及被识别到&#xff0c;就会被主机判定成USB 2.0的设备。 Figure 1-1 USB 3.0标…

WorldWind Android上加载白模数据

这篇文章介绍下如何加载白模数据。这个白模数据的格式是shapefile格式的文件。白模数据拷贝到手机本地&#xff0c;然后读取白模数据&#xff0c;进行加载展示。 worldwind android本身是不支持加载白模数据的&#xff0c;但是可以根据现有提供的加载Polygons的方式&#xff0c…