枚举也就是一一列举,常用来表示那些可以明确范围的集合,比方说性别,季节,星期,月份等。
在 JDK 1.5 才出现枚举类,在没有出现枚举类之前,我们要表示几个确定的值通常会使用常量来表示,形如
public static final Integer SPRING = 1; public static final Integer SUMMER = 2; public static final Integer FALL = 3; public static final Integer WINTER = 4;
我们可以使用枚举类来表示,这也就是最简单的枚举。
enum Season{ SPRING,SUMMER,FALL,WINTER; }
那么枚举类和定义常量相比有什么优势呢?
安全,我们看上面的代码可以知道,使用常量表示的季节都是 Integer 类型的,而这个类型的数据范围太大了,而使用枚举就限制了数据的域。枚举可以理解为几个常量的集合,数据不太会改变,使用枚举之后语义更加明确,因为数据域不大。
关于枚举类,有几点需要注意:
-
enum 和 class ,interface 的地位一样
-
使用 enum 定义的枚举类默认继承了 java.lang.Enum,而不是继承 Object 类。枚举类可以实现一个或多个接口,不能再继承其他类了。
-
枚举类的所有实例都必须放在第一行展示,不需使用 new 关键字,不需显式调用构造器。自动添加 public static final 修饰。
-
枚举类的构造器只能是私有的。
关于第 4 点,我要说枚举类的定义是单例模式的,单例模式要求构造器私有化,不允许在外部创建新的对象,你想呀,枚举类的作用就是准确的表示出同一类别下的不同数据。在我们定义的时候已经创建好了,所以跟本不需要也不能在外部继续创建新的对象。故,需要将构造器私有化。
枚举类说的通俗点就是被阉割的类,我们使用类可以创建对象,而枚举类在定义的时候就会指定创建的对象有哪些。你没有显示的写代码创建,不过是由于 JVM 自动给你加上去了。待会看看枚举类被反编译之后的情况就会理解。
枚举类中可以定义属性和方法。
enum Season{ SPRING("春天","一年之计在于春"),SUMMER("夏天","夏天好热 ~ "), FALL("秋天","秋水共长天一色"),WINTER("冬天","冬天好冷 ~ "); // 添加枚举对象的名称 private final String name; // 添加枚举对象的描述 private final String desc; private Season(String name,String desc){ this.name = name; this.desc = desc; } public String getName(){ return name; } public String getDesc(){ return desc; } }
我们可以看到,有一个带参的私有构造函数,所以在定义枚举的时候可以直接赋值,而调用创建对象是由虚拟机自动完成的,还可以添加更多的属性,我们可以正常使用枚举对象。
// 获取所有的枚举对象,返回的是数组Season[] values = Season.values(); for (Season season : values) { System.out.println(season.getName() + " : " + season.getDesc()); } 春天 : 一年之计在于春 夏天 : 夏天好热 ~ 秋天 : 秋水共长天一色 冬天 : 冬天好冷 ~
枚举类中实现抽象方法
这肯定有点迷糊,我们知道含有抽象方法的类是抽象类,那为什么枚举类不是 abstract 的也可以含有抽象方法呢 ?我们先来看看实现,待会说原因。

