面试官:来,讲一下枚举类型在开发时中实际应用场景!
off999 2025-06-15 18:37 53 浏览 0 评论
一.基本介绍
枚举是 JDK 1.5 新增的数据类型,使用枚举我们可以很好的描述一些特定的业务场景,比如一年中的春、夏、秋、冬,还有每周的周一到周天,还有各种颜色,以及可以用它来描述一些状态信息,比如错误码等。
枚举类型不止存在在 Java 语言中,在其它语言中也都能找到它的身影,例如 C# 和 Python 等,但我发现在实际的项目中使用枚举的人很少,所以本文就来聊一聊枚举的相关内容,好让朋友们对枚举有一个大概的印象,这样在编程时起码还能想到有“枚举”这样一个类型。
二.枚举的使用方式
很多人不使用枚举的一个重要的原因是对枚举不够熟悉,那么我们就先从枚举的 7 种使用方法说起。
1.常量
在JDK1.5 之前,我们定义常量都是:public static final… 。现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法。
public enum Color {
RED, GREEN, BLANK, YELLOW
}
2.switch
JDK1.6之前的switch语句只支持int,char,enum类型,使用枚举,能让我们的代码可读性更强。
enum Signal {
GREEN, YELLOW, RED
}
public class TrafficLight {
Signal color = Signal.RED;
public void change() {
switch (color) {
case RED:
color = Signal.GREEN;
break;
case YELLOW:
color = Signal.RED;
break;
case GREEN:
color = Signal.YELLOW;
break;
}
}
}
3.向枚举中添加新方法
如果打算自定义自己的方法,那么必须在enum实例序列的最后添加一个分号。
public enum Color {
RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
// 成员变量
private String name;
private int index;
// 构造方法
private Color(String name, int index) {
this.name = name;
this.index = index;
}
// 普通方法
public static String getName(int index) {
for (Color c : Color.values()) {
if (c.getIndex() == index) {
return c.name;
}
}
return null;
}
// get set 方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
}
4.覆盖枚举的方法
下面给出一个toString()方法覆盖的例子。
public enum Color {
RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
// 成员变量
private String name;
private int index;
// 构造方法
private Color(String name, int index) {
this.name = name;
this.index = index;
}
//覆盖方法
@Override
public String toString() {
return this.index+"_"+this.name;
}
}
5.实现接口
所有的枚举都继承自java.lang.Enum类。由于Java 不支持多继承,所以枚举对象不能再继承其他类。
public interface Behaviour {
void print();
String getInfo(); } public enum Color implements Behaviour{
RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
// 成员变量
private String name;
private int index;
// 构造方法
private Color(String name, int index) {
this.name = name;
this.index = index;
} //接口方法
@Override
public String getInfo() {
return this.name;
}
//接口方法
@Override
public void print() {
System.out.println(this.index+":"+this.name);
}
}
6.使用接口组织枚举
public interface Food {
enum Coffee implements Food{
BLACK_COFFEE,DECAF_COFFEE,LATTE,CAPPUCCINO
}
enum Dessert implements Food{
FRUIT, CAKE, GELATO
}
}
/**
* 测试继承接口的枚举的使用(by 大师兄 or 大湿胸。)
*/
private static void testImplementsInterface() {
for (Food.DessertEnum dessertEnum : Food.DessertEnum.values()) {
System.out.print(dessertEnum + " ");
}
System.out.println();
//我这地方这么写,是因为我在自己测试的时候,把这个coffee单独到一个文件去实现那个food接口,而不是在那个接口的内部。
for (CoffeeEnum coffee : CoffeeEnum.values()) {
System.out.print(coffee + " ");
}
System.out.println();
//搞个实现接口,来组织枚举,简单讲,就是分类吧。如果大量使用枚举的话,这么干,在写代码的时候,就很方便调用啦。
//还有就是个“多态”的功能吧,
Food food = Food.DessertEnum.CAKE;
System.out.println(food);
food = CoffeeEnum.BLACK_COFFEE;
System.out.println(food);
}
7.关于枚举集合的使用
java.util.EnumSet和java.util.EnumMap是两个枚举集合。EnumSet保证集合中的元素不重复;EnumMap中的 key是enum类型,而value则可以是任意类型。关于这个两个集合的使用就不在这里赘述,可以参考JDK文档。
下面是我自己的测试代码。
public class EnumTest {
public static void main(String[] args) {
List<ColorEnum> list = new ArrayList<ColorEnum>();
list.add(ColorEnum.RED);
list.add(ColorEnum.RED); // 重复元素
list.add(ColorEnum.YELLOW);
list.add(ColorEnum.GREEN);
// 去掉重复数据
EnumSet<ColorEnum> enumSet = EnumSet.copyOf(list);
System.out.println("去重:" + enumSet);
// 获取指定范围的枚举(获取所有的失败状态)
EnumSet<ErrorCodeEnum> errorCodeEnums = EnumSet.range(ErrorCodeEnum.ERROR, ErrorCodeEnum.UNKNOWN_ERROR);
System.out.println("所有失败状态:" + errorCodeEnums);
}
}
enum ColorEnum {
RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLOW("黄色", 4);
private String name;
private int index;
private ColorEnum(String name, int index) {
this.name = name;
this.index = index;
}
}
enum ErrorCodeEnum {
SUCCESS(1000, "success"),
ERROR(2001, "parameter error"),
SYS_ERROR(2002, "system error"),
NAMESPACE_NOT_FOUND(2003, "namespace not found"),
NODE_NOT_EXIST(3002, "node not exist"),
NODE_ALREADY_EXIST(3003, "node already exist"),
UNKNOWN_ERROR(9999, "unknown error");
private int code;
private String msg;
ErrorCodeEnum(int code, String msg) {
this.code = code;
this.msg = msg;
}
public int code() {
return code;
}
public String msg() {
return msg;
}
}
三.为什么使用枚举
1.假如不使用枚举
在枚举没有诞生之前,也就是 JDK 1.5 版本之前,我们通常会使用 int 常量来表示枚举,实现代码如下:
public static final int COLOR_RED = 1;
public static final int COLOR_BLUE = 2;
public static final int COLOR_GREEN = 3;
但是使用 int 类型可能存在两个问题:
第一, int 类型本身并不具备安全性,假如某个程序员在定义 int 时少写了一个 final 关键字,那么就会存在被其他人修改的风险,而反观枚举类,它“天然”就是一个常量类,不存在被修改的风险;
第二,使用 int 类型的语义不够明确,比如我们在控制台打印时如果只输出 1...2...3 这样的数字,我们肯定不知道它代表的是什么含义。
那有人就说了,那就使用常量字符呗,这总不会还不知道语义吧?实现示例代码如下:
public static final String COLOR_RED = "RED";
public static final String COLOR_BLUE = "BLUE";
public static final String COLOR_GREEN = "GREEN";
但是这样同样存在一个问题,有些初级程序员会不按套路出牌,他们可能会直接使用字符串的值进行比较,而不是直接使用枚举的字段,实现示例代码如下:
public class EnumTest {
public static final String COLOR_RED = "RED";
public static final String COLOR_BLUE = "BLUE";
public static final String COLOR_GREEN = "GREEN";
public static void main(String[] args) {
String color = "BLUE";
if ("BLUE".equals(color)) {
System.out.println("蓝色");
}
}
}
这样当我们修改了枚举中的值,那程序就凉凉了。
2.枚举使用场景
枚举的常见使用场景是单例,它的完整实现代码如下:
public class Singleton {
// 枚举类型是线程安全的,并且只会装载一次
private enum SingletonEnum {
INSTANCE;
// 声明单例对象
private final Singleton instance;
// 实例化
SingletonEnum() {
instance = new Singleton();
}
private Singleton getInstance() {
return instance;
}
}
// 获取实例(单例对象)
public static Singleton getInstance() {
return SingletonEnum.INSTANCE.getInstance();
}
private Singleton() {
}
// 类方法
public void sayHi() {
System.out.println("Hi,Java.");
}
}
class SingletonTest {
public static void main(String[] args) {
Singleton singleton = Singleton.getInstance();
singleton.sayHi();
}
}
因为枚举只会在类加载时装载一次,所以它是线程安全的。
3.枚举为什么是线程安全的
这一点要从枚举最终生成的字节码说起,首先我们先来定义一个简单的枚举类:
public enum ColorEnumTest {
RED, GREEN, BLANK, YELLOW;
}
然后我们再将上面的那段代码编译为字节码,具体内容如下:
public final class ColorEnumTest extends java.lang.Enum<ColorEnumTest> {
public static final ColorEnumTest RED;
public static final ColorEnumTest GREEN;
public static final ColorEnumTest BLANK;
public static final ColorEnumTest YELLOW;
public static ColorEnumTest[] values();
public static ColorEnumTest valueOf(java.lang.String);
static {};
}
从上述结果可以看出枚举类最终会被编译为被 final 修饰的普通类,它的所有属性也都会被 static 和 final 关键字修饰,所以枚举类在项目启动时就会被 JVM 加载并初始化,而这个执行过程是线程安全的,所以枚举类也是线程安全的类。
4.枚举的比较
我们在枚举比较时使用 == 就够了,因为枚举类是在程序加载时就创建了(它并不是 new 出来的),并且枚举类不允许在外部直接使用 new 关键字来创建枚举实例,所以我们在使用枚举类时本质上只有一个对象,因此在枚举比较时使用 == 就够了。
并且我们在查看枚举的 equlas() 源码会发现,它的内部其实还是直接调用了 == 方法,源码如下:
public final boolean equals(Object other) {
return this==other;
}
四.总结
本文我们介绍了枚举类的 7 种使用方法:常量、switch、枚举中添加方法、覆盖枚举方法、实现接口、在接口中组织枚举类和使用枚举集合等,然后讲了如果不使用枚举类使用 int 类型和 String 类型存在的一些弊端:语义不够清晰、容易被修改、存在被误用的风险,所以我们在适合的环境下应该尽量使用枚举类。并且我们还讲了枚举类的使用场景——单例,以及枚举类为什么是安全的,最后我们讲了枚举比较的小技巧,希望本文对你有帮助。
相关推荐
- 愤怒的小鸟变形金刚破解版(愤怒的小鸟愤怒的小鸟变形金刚破解版)
-
怒鸟红擎天柱最强。变形金刚的首领,拥有大型卡车的变身形态,是新手登场的必备角色。主要用来过掉第一章的剧情任务,升级后加护甲和武器,所以不需要太多的培养,前期一级就足够了。属性:护甲1级、武器1级、车辆...
- 12360订票官网下载软件(下载12360订票软件新版本)
-
应该是12306app怎么订票?首先我们下载一个12306app,然后凭自己的身份证号码和手机号码注册,注册成功之后,然后再登录12306网站,进行人证核验,核验成功之后就可以订票了,首先打开1230...
- lol官网入口(Sxr.lol官网入口)
-
英雄联盟官网如下:https://lol.qq.com。进入官网,你可以看到官网的详细信息,里面有游戏介绍,视频,资料,赛事,活动等一系列内容。官网具有非常准确的官方信息,大家需要了解相关游戏资讯,可...
- 24小时在线直播免费看(24小时播放视频免费观看)
-
1、首先,打开抖音之后,进入视频播放页面,点击右下角的“我”,进入抖音个人中心,再点击右上角的“三”按钮。2、进入抖音设置之后,选择其中的“反馈与帮助”。3、进入反馈与帮助之后,选择其中的“直播(权限...
- 汽车网(汽车网新车报价大全)
-
1.部分内容有真实性,部分内容可能存在虚假或夸大情况。2.因为汽车江湖网是一个汽车资讯平台,其发布的内容主要来源于汽车行业的新闻、评论、测评等,其中一些内容可能会被厂商或广告商进行操控或干扰,导致...
- 无货源一件代发平台(云仓一件代发)
-
【一】1688【阿里巴巴】国内知名批发和一件代发平台,类目也是很齐全的产品很丰富的一个平台,基本上我们需要的产品上面都有,很多店主一件代发也都是来自于这个平台。【二】一起做网店和搜款网,基本上覆盖广州...
- 快吧游戏盒子下载安装(快吧 游戏 盒子)
-
只是一个游戏盒子的下载,在这个应用中心里找到这样的游戏盒子就能够直接下来的。快吧游戏盒子可以通过以下几个步骤进行下载。1.打开你的手机应用商店,例如苹果应用商店或安卓应用商店。2.在应用商店中搜索...
- 午夜成人小电影(我想看免费午夜电影)
-
看你喜好是什么了,你喜欢的就是好看的,午夜还是建议看一下剧情类的,千万不要看恐怖片,除非你想失眠。对于男生深夜观看悲伤电影,以下是一些适合的选择:1."肖申克的救赎"(TheSha...
- 2025最火网名(2025最火网名最新版)
-
1、绝世好女人2、气≦贯长虹3、滿眼浮華4、好久没换,改什么好5、成功可望6、小西福7、突然,好懷念8、翡ル翠鸿图9、陈运锋10、桃花峪运维朱恒彬11、金safety12、指间轻纱°13、花≦好月圆1...
- 163免费邮箱登录入口(126免费邮箱登录入口)
-
是https://mail.163.com/。原因是163邮箱是中国最早的电子邮件服务提供商之一,拥有稳定的运营和使用群体。用户可以通过网页直接登录,进行收发邮件,具有便捷、快速的特点。另外,163...
-
- 中国联通腾讯(中国联通腾讯大王卡)
-
当时,联通免除抖音的流量费用,是因为联通和字节跳动公司有合作。现在合作已经结束了,所以就不免抖音流量了。其实可以理解为字节跳动花钱为大伙买流量,大伙免费用的意思。但是现在使用抖音的人这么多,人口基数这么大,字节跳动再买这么大的流量也买不起。...
-
2026-02-01 19:43 off999
-
- 酷狗音乐下载歌曲(酷狗音乐下载歌曲在哪能找到)
-
本地音乐就是已下载的音乐。1、打开音乐,点击我的。2、点击本地。3、然后就看到已下载和推荐下载的音乐了。4、点击向下的箭头就可以下载了。意思就是在手机里面下载的音乐,保存到手机上面的就是本地音乐,在手机自带的音乐里面就能下载首先我们进入到...
-
2026-02-01 19:15 off999
- 免费法律咨询24小时在线(青岛免费法律咨询24小时在线)
-
没有这样的律师二十四小时不休息。首先要说的是,提问者二十四小时不休息等着律师二十四小时免费为你解答法律咨询呀?提这样的问题过过大脑,律师是活生生的人,不是电脑和机器人,二十四小时不休息的,这样的人想要...
- 无需root权限的游戏修改器
-
游戏修改器都需要root。原因如下:root意思是获得超级用户权限,root后才能打开系统文件,游戏文件都在系统文件里,不root是打不开系统文件的,就更别提修改了。你好游戏修改器都是修改系统的内...
- 网络推广平台哪家公司最好(网上怎么赚钱一天500)
-
1,依附于搜索引擎,针对各个搜索引擎做的,叫sem,包括了竞价和优化seo,这是目前最广泛应用的平台。2,微博,目前微博营销已经很火热,用户量巨大,也能带动产品的销售,尤其做电子商务的,一定重视微博。...
欢迎 你 发表评论:
- 一周热门
-
-
抖音上好看的小姐姐,Python给你都下载了
-
全网最简单易懂!495页Python漫画教程,高清PDF版免费下载
-
飞牛NAS部署TVGate Docker项目,实现内网一键转发、代理、jx
-
win7系统还原步骤图解(win7还原电脑系统的步骤)
-
Python 3.14 的 UUIDv6/v7/v8 上新,别再用 uuid4 () 啦!
-
python入门到脱坑 输入与输出—str()函数
-
16949认证费用是多少(16949审核员太难考了)
-
linux软件(linux软件图标)
-
Python三目运算基础与进阶_python三目运算符判断三个变量
-
(新版)Python 分布式爬虫与 JS 逆向进阶实战吾爱分享
-
- 最近发表
- 标签列表
-
- python计时 (73)
- python安装路径 (56)
- python类型转换 (93)
- python进度条 (67)
- python吧 (67)
- python的for循环 (65)
- python格式化字符串 (61)
- python静态方法 (57)
- python列表切片 (59)
- python面向对象编程 (60)
- python 代码加密 (65)
- python串口编程 (77)
- python封装 (57)
- python写入txt (66)
- python读取文件夹下所有文件 (59)
- python操作mysql数据库 (66)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python多态 (60)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)
