Java中枚举类型
一. 说明
枚举是一个带有命名的整型常数集合,用于声明一组带标识符的常数。枚举在曰常生活其实中很常见,例如一个人的性别只能是“男”或者“女”,一周的星期只能是 7 天中的一个等等。当一个变量只有几种固定可取的值时,我们就可以将它定义为枚举类型。
在 JDK 1.5 之前没有枚举类型,那时候一般是用接口常量来替代,我们现在就可以用enum枚举类型来贴切地表示这种常量了。
二. 为什么命名要用枚举
需求分析
比如我们现在想编写一个游戏,游戏中有上下左右4个方向 ,我们可以创建一个类,在该类中定义出上下左右四个方向常量。
这时我们可以有以下几种实现方式。
2. 第一种实现方式
public class GameStaticFinal {
//上
public static final int UP = 1;
//下
public static final int DOWN = 2;
//左
public static final int LEFT = 3;
//右
public static final int RIGHT = 4;
}
缺点:
1. 代码中必须带有static final;
2. 1、2、3、4 这些命名都不能做到 “见名知意”。
3. 第二种实现方式
我们把上面的实现改造一下,把数字改成字符串。
public class GameStaticFinal {
//上
public static final String UP = "UP";
//下
public static final String DOWN = "DOWN";
//左
public static final String LEFT = "LEFT";
//右
public static final String RIGHT = "RIGHT";
}
缺点:
1. 需要记住 "UP"、"DOWN" 这些英文字符串;
2. 用equals判断时,"UP".equals(GameStaticFinal.UP),"UP"写死了,这属于硬编码,不灵活。
看来以上两种实现方式都存在一些缺点,那我们可以怎么改进实现呢?这时候我们就可以用枚举来实现了。
三. 定义枚举
1. 创建枚举类
public enum GameEnum {
UP, //上
DOWN, //下
LEFT, //左
RIGHT; //右
}
2. 使用注意事项
我们在使用枚举时,要注意以下几点:
定义枚举时要使用Enum关键字;
命名时类名尽量要带Enum , 常量全部大写,多个单词之间用_分割;
枚举是一种特殊的常量类;
默认的构造方法必须是私有的;
枚举里的常量相当于枚举对象;
常量之间用逗号分隔,用分号结尾;
四. 具体应用
我们可以通过如下几个案例来展示枚举具体该怎么使用。
1. 配合switch使用
我们可以在switch中配合枚举进行列举。
//获取里边的常量
Test01Enum e = Test01Enum.UP;
switch (e) {
case UP:
break;
case LEFT:
break;
case DOWN:
break;
case RIGHT:
break;
case SKIP:
break;
default:
break;
}
2. 定义带参数的枚举常量
public enum Test03Enum {
//四套: success code msg 信息 整合的对象
SELECT_SUCCESS(true,1001,"查询成功"),
DELETE_SUCCESS(true,1002,"删除成功"),
UPDATE_ERROR(false,1003,"更新失败"),
ADD_ERROR(false,1004,"添加失败");
//返回码: success code msg
private boolean success;
private int code;
private String msg;
//构造器方法
Test03Enum(boolean success, int code, String msg) {
this.success = success;
this.code = code;
this.msg = msg;
}
public boolean isSuccess() {
return success;
}
public int getCode() {
return code;
}
public String getMsg() {
return msg;
}
}
测试使用:
public class Test03Main {
public static void main(String[] args) {
//1.获取有参构造器的枚举对象
Test03Enum e = Test03Enum.SELECT_SUCCESS;
System.out.println(e.isSuccess());
System.out.println(e.getCode());
System.out.println(e.getMsg());
}
}
在集合中使用枚举
我们也可以把枚举作为集合的泛型,将集合与枚举结合一起使用。
public enum Test07Enum {
DOWN,UP,LEFT,SKIP,RIGHT;
}
public class Test07Main {
public static void main(String[] args) {
//1.创建一个泛型是枚举的集合
Listlist = new ArrayList<>();
//2. 添加元素
list.add(Test07Enum.UP);
list.add(Test07Enum.UP);
list.add(Test07Enum.DOWN);
for (Test07Enum test07Enum : list) {
System.out.println(test07Enum);
}
System.out.println("=======================================");
//set 当中的元素是不重复的,所以,我可以去重
// 利用 EnumSet可以去重
EnumSettest07Enums = EnumSet.copyOf(list);
System.out.println(test07Enums);
System.out.println("=================================");
// 利用 EnumSet 可以返回一个 EnumSet类型的集合 : 范围: 区间
EnumSetrange = EnumSet.range(Test07Enum.UP, Test07Enum.SKIP);
System.out.println(range);
System.out.println("EnumMap==========================");
//EnumMap: key是枚举 类型 : 参数是枚举 的class类型
EnumMap<test07enum,string> map = new EnumMap<>(Test07Enum.class);
map.put(Test07Enum.UP,"上");
map.put(Test07Enum.DOWN,"下");
String s = map.get(Test07Enum.UP);
System.out.println(s);
//EnumMap 数组结构 : 专门为 枚举 类型设计的map结构
}
}
五. 枚举为什么是线程安全的?
我们去找工作时,有些面试官会考察关于枚举的内容,比如会问枚举是不是线程安全的,为什么?要想弄明白这个问题,我们可以使用一个命令来验证一下枚举类。
javap xxx.class
我们在控制台对某个字节码文件执行上述命令之后,可以得到如下效果:
从上图中可以看出,枚举类最终会被编译为被final 修饰的普通类,我们知道常量就是用static final 来修饰的,所以枚举值就是常量值,无法被修改。另外枚举类在项目启动时就会被 JVM 加载并初始化,而这个执行过程肯定是线程安全的,所以枚举类也是线程安全的类。

相关推荐HOT
更多>>
怎么将string字符串转换成byte[]数组?
例如,使用默认字符集转换可以如下所示: 也可以指定字符集: 这将使用UTF-8字符集将字符串转换成字节数组。详情>>
2023-04-25 17:14:58
如何禁用浏览器的前进和后退功能
URL) 本质就是在进入页面或者路由跳转的时候在历史记录中保存一条没有意义的记录,这样用户在点击前后后退按钮的时候就没有效果。详情>>
2023-04-19 10:36:58
react传值是什么意思?
react是组件化的框架,组件实例间作用域是互相隔离的,所以组件间的通信就变成了开发过程中常常要解决的问题,根据场景可以分为: 父子组...详情>>
2023-04-18 17:23:22
使用IE浏览器遇见过哪些兼容问题?
在IE6中,块元素设置float并且有水平方向的margin时,margin显示出来会比设置的值大,会导致最后一块元素被顶到下面去; 解决办法:在CSS文...详情>>
2023-04-12 09:21:12