文章目录
- 1. 概念
- 1. 什么时候用枚举
- 2. 语法
- 3. 枚举集合
- 4. 枚举 API
- 5. 枚举的本质
1. 概念
1. 什么时候用枚举
程序中某个变量取值仅限于集合中的元素。此时,可将这些数据集合定义为枚举类型。
2. 语法
枚举类与类、接口是同等地位的,他可以实现多个接口,可以有构造器 ,方法 ,属性等等。
枚举类和普通类的区别在于,枚举类默认继承 java.lang.Enum 类,其中 java.lang.Enum 类实现了 java.lang.Serializable 和 java.lang.Comparable 接口;所有枚举类默认被 final 修饰,即枚举类不可被继承;所有构造器默认被 private 修饰,也只能被 private 修饰;枚举类的所有实例必须位于第一行,默认被 public static final 修饰。
枚举实例可以有 n 个参数,如果 n 不为 0,则要求枚举类中必须存在一个包含 n 个参数的构造器,如:
enum Color implements Print{
//每个颜色都是枚举类的一个实例,并且构造方法要和枚举类的格式相符合。
//如果实例后面有其他内容,实例序列结束时要加分号。
Red("红色", 1), Green("绿色", 2), Blue("蓝色", 3), Yellow("黄色", 4), Glay;
String name;
int index;
Color() {}
Color(String name, int index) {
this.name = name;
this.index = index;
}
//重写接口中的方法
@Override
public void print() {
System.out.println(this.name);
}
//因为默认继承了 Enum 父类,所以可以重写父类中的方法
@Override
public String toString() {
return this.index + ":" + this.name;
}
public void showAllColors() {
//values是Color实例的数组,在通过index和name可以获取对应的值。
for (Color color : Color.values()) {
System.out.println(color.index + ":" + color.name);
}
}
}
枚举类型对象之间的值比较:使用 == 直接来比较值,枚举类 Enum 已经重写了 equals 方法
//Enum 源码
public final boolean equals(Object other) {
return this==other;
}
3. 枚举集合
EnumSet 存储 Enum 类型的集合,且集合元素不重复,因为 EnumSet 是一个抽象类,所以要用它的话,需要子类去继承它;EnumMap 存储 key 为 Enum 类型,value 为任意类型的键值对
public class 枚举类集合 {
public static void main(String[] args) {
EnumMap<Color, String> map = new EnumMap<Color, String>(Color.class);
map.put(Color.Blue, "Blue");
map.put(Color.Yellow, "Yellow");
map.put(Color.Red, "Red");
System.out.println(map.get(Color.Red));
}
}
如果枚举类数量比较多,可以使用接口来组织枚举类
class TestEnumByInterface {
public static void main(String[] args) {
Food cf = chineseFood.dumpling; // 没有定义在接口里面
Food food = Food.JapaneseFood.fishpiece; //定义在接口里面,接口中的枚举需要用 接口名.枚举名 来调用
food = Food.Coffee.BLACK_COFFEE;
for (Food food1 : chineseFood.values()) {
System.out.println(food1);
}
for (Food food1 : Food.JapaneseFood.values()) {
System.out.println(food1);
}
}
}
interface Food { // 接口里面定义多个枚举类
enum JapaneseFood implements Food {
suse, fishpiece;
}
enum Coffee implements Food {
BLACK_COFFEE, DECAF_COFFEE, ESPRESSO, LATTE, CAPPUCCINO, TEA, HERB_TEA;
}
}
enum chineseFood implements Food { //这个枚举类没有定义在接口里面
dumpling, tofu;
}
//结果
dumpling
tofu
suse
fishpiece
4. 枚举 API
- String name():获取枚举实例名称
- int ordinal():获取枚举的位置(下标,默认初始值为 0,如果是自定义的话,就返回自定义的整数值 )
- valueof(String msg):通过枚举实例名称获取其对应的枚举类型
- values():获取枚举类中的所有枚举值(枚举实例),返回一个包含所有枚举实例的数组,枚举类名.values()
5. 枚举的本质
枚举本质上是通过普通的类来实现的,只是编译器为我们进行了处理。每个枚举类型都继承自 java.lang.Enum,并自动添加了 values 和 valueOf 方法;每个枚举常量(即枚举实例)是一个静态常量字段,使用内部类实现,该内部类继承了枚举类。
第一,所有枚举常量都通过静态代码块来进行初始化,即在类加载期间就初始化;第二,通过把 clone 定义为 final 修饰、readObject 定义为 private 来保证了每个枚举类型及枚举常量都是不可变的。可以利用枚举的这两个特性来实现线程安全的单例