Java 枚举
枚举概述
什么是枚举
枚举是一个被命名的整型常数的集合,枚举在日常生活中很常见,例如表示星期的 SUNDAY、MONDAY、TUESDAY、WEDNESDAY、THURSDAY、FRIDAY、SATURDAY
就是一个枚举。通俗来说,枚举就是一个对象的所有可能取值的集合
来自:维基百科 枚举
普通代码实现枚举
使用常量类来代替枚举类
class WeekDay {
public static final Integer MONDAY = 1;
public static final Integer TUESDAY = 2;
public static final Integer WEDNESDAY = 3;
public static final Integer THURSDAY = 4;
public static final Integer FRIDAY = 5;
public static final Integer SATURDAY = 6;
public static final Integer SUNDAY = 7;
}
需要传入指定内容的方法
public class Employee {
/**
* 指定员工在哪一天休息
*/
private Integer restDay;
public Integer getRestDay() {
return restDay;
}
public void setRestDay(Integer restDay) {
if (restDay > 7 || restDay < 1){
throw new RuntimeException("完蛋");
}
this.restDay = restDay;
}
}
可以在内容方法中限定传入的数值,但是数值的合理性无法交给编译器去判断,会增大代码复杂度。
测试类
public static void main(String[] args) {
Employee employee = new Employee();
employee.setRestDay(43);
}
枚举类是如何解决方法传入内容检查的?
枚举类详解
示例代码
枚举类
public enum WeekDayEnum {
MONDAY(1, "星期一"),
TUESDAY(2, "星期二"),
WEDNESDAY(3, "星期三"),
THURSDAY(4, "星期四"),
FRIDAY(5, "星期五"),
SATURDAY(6, "星期六"),
SUNDAY(7, "星期日"),
;
private int code;
private String desc;
WeekDayEnum(int code, String desc) {
this.code = code;
this.desc = desc;
}
public int getCode() {
return code;
}
public String getDesc() {
return desc;
}
}
- 枚举类结尾使用
Enum
命名- 内容使用大写字母,单词之间使用下划线分隔
- 构造方法可带参数可不带
接收枚举方法
public class WorkDay {
private WeekDayEnum workDay;
public void setWorkDay(WeekDayEnum workDay){
this.workDay = workDay;
}
}
测试方法
public static void main(String[] args) {
WorkDay workDay = new WorkDay();
workDay.setWorkDay(WeekDayEnum.MONDAY);
}
由于方法只接收指定的枚举类型,因此只有指定枚举类中的元素时编译器会通过。
源码解析
反编译枚举类内容
// Decompiled by DJ v3.12.12.100 Copyright 2015 Atanas Neshkov Date: 2022/1/6 9:53:24
// Home Page: http://www.neshkov.com/dj.html - Check often for new version!
// Decompiler options: packimports(3)
// Source File Name: WeekDayEnum.java
package com.mochen.advance.enums.real;
public final class WeekDayEnum extends Enum
{
public static WeekDayEnum[] values()
{
return (WeekDayEnum[])$VALUES.clone();
}
public static WeekDayEnum valueOf(String name)
{
return (WeekDayEnum)Enum.valueOf(com/mochen/advance/enums/real/WeekDayEnum, name);
}
private WeekDayEnum(String s, int i, int code, String desc)
{
super(s, i);
this.code = code;
this.desc = desc;
}
public int getCode()
{
return code;
}
public String getDesc()
{
return desc;
}
public static final WeekDayEnum MONDAY;
public static final WeekDayEnum TUESDAY;
public static final WeekDayEnum WEDNESDAY;
public static final WeekDayEnum THURSDAY;
public static final WeekDayEnum FRIDAY;
public static final WeekDayEnum SATURDAY;
public static final WeekDayEnum SUNDAY;
private int code;
private String desc;
private static final WeekDayEnum $VALUES[];
static
{
MONDAY = new WeekDayEnum("MONDAY", 0, 1, "\u661F\u671F\u4E00");
TUESDAY = new WeekDayEnum("TUESDAY", 1, 2, "\u661F\u671F\u4E8C");
WEDNESDAY = new WeekDayEnum("WEDNESDAY", 2, 3, "\u661F\u671F\u4E09");
THURSDAY = new WeekDayEnum("THURSDAY", 3, 4, "\u661F\u671F\u56DB");
FRIDAY = new WeekDayEnum("FRIDAY", 4, 5, "\u661F\u671F\u4E94");
SATURDAY = new WeekDayEnum("SATURDAY", 5, 6, "\u661F\u671F\u516D");
SUNDAY = new WeekDayEnum("SUNDAY", 6, 7, "\u661F\u671F\u65E5");
$VALUES = (new WeekDayEnum[] {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
});
}
}
反编译后发现所谓的枚举类就是一个继承了 Enum
类的枚举类,会自动生成两个方法 values()
获取所有的枚举元素, valueOf()
根据枚举元素名称获取到指定的元素。枚举类的本质其实就是一组静态常量对象,在 static
方法块中所有的元素进行初始化,可以发现在编写源码时设置的参数是两个,但在反编译后参数变成了四个,第一个是元素的名称,第二个是序号从0开始,接下来就是我们设置的参数。可以看到在构造函数中前两个参数交给了父类的构造函数去处理,在父类中也是简单的将这两个参数储存。
这是一个构造函数有参数的枚举类,那么无参的枚举类是什么样子呢?
- 源码
public enum NoParamEnum {
HELLO,
WORLD,
MY,
NAME,
IS,
LXC,
;
NoParamEnum(){}
}
- 反编译
// Decompiled by DJ v3.12.12.100 Copyright 2015 Atanas Neshkov Date: 2022/1/6 10:38:42
// Home Page: http://www.neshkov.com/dj.html - Check often for new version!
// Decompiler options: packimports(3)
// Source File Name: NoParamEnum.java
package com.mochen.advance.enums.real;
public final class NoParamEnum extends Enum
{
public static NoParamEnum[] values()
{
return (NoParamEnum[])$VALUES.clone();
}
public static NoParamEnum valueOf(String name)
{
return (NoParamEnum)Enum.valueOf(com/mochen/advance/enums/real/NoParamEnum, name);
}
private NoParamEnum(String s, int i)
{
super(s, i);
}
public static final NoParamEnum HELLO;
public static final NoParamEnum WORLD;
public static final NoParamEnum MY;
public static final NoParamEnum NAME;
public static final NoParamEnum IS;
public static final NoParamEnum LXC;
private static final NoParamEnum $VALUES[];
static
{
HELLO = new NoParamEnum("HELLO", 0);
WORLD = new NoParamEnum("WORLD", 1);
MY = new NoParamEnum("MY", 2);
NAME = new NoParamEnum("NAME", 3);
IS = new NoParamEnum("IS", 4);
LXC = new NoParamEnum("LXC", 5);
$VALUES = (new NoParamEnum[] {
HELLO, WORLD, MY, NAME, IS, LXC
});
}
}
可以看到原理并没有变化,只是在声明枚举元素的时候可以将括号省略。
同时,也可以使用自动生成的两个方法来获取到枚举类的信息。
WeekDayEnum[] values = WeekDayEnum.values();
for (WeekDayEnum value : values) {
System.out.println(value);
}
System.out.println(WeekDayEnum.valueOf("MONDAY"));
MONDAY
TUESDAY
WEDNESDAY
THURSDAY
FRIDAY
SATURDAY
SUNDAY
MONDAY
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)