枚举是什么?
维基百科的定义
在数学和计算机科学理论中,一个集的枚举是列出某些有穷序列集的所有成员的程序,或者是一种特定类型对象的计数。这两种类型经常(但不总是)重叠。 枚举在日常生活中很常见,例如表示星期的SUNDAY、MONDAY、TUESDAY、WEDNESDAY、THURSDAY、FRIDAY、SATURDAY就是一个枚举。
枚举在C/C++/c#中,是一个被命名的整型常数的集合
enum 枚举名{
标识符[=整型常数],
标识符[=整型常数],
...
标识符[=整型常数]
}枚举变量;
如果枚举没有初始化,即省掉"=整型常数"时, 则从第一个标识符开始,顺次赋给标识符0, 1, 2, ...。但当枚举中的某个成员赋值后,其后的成员按依次加1的规则确定其值。
随着计算机的不断普及,程序不仅只用于数值计算,还更广泛地用于处理非数值的数据。例如:性别、月份、星期几、颜色、单位名、学历、职业等,都不是数值数据。 在其它程序设计语言中,一般用一个数值来代表某一状态,这种处理方法不直观,易读性差。如果能在程序中用自然语言中有相应含义的单词来代表某一状态,则程序就很容易阅读和理解。也就是说,事先考虑到某一变量可能取的值,尽量用自然语言中含义清楚的单词来表示它的每一个值,这种方法称为枚举方法,用这种方法定义的类型称枚举类型。
java的枚举
java的枚举类型(enum type), 是指由一组固定的常量组成合法的类型。Java中由关键字enum来定义一个枚举类型。下面就是java枚举类型的定义。
public enum Week {
SUNDAY,
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY;
}
书写注意
- 使用关键字
enum - 类型名称,比如这里的
Week - 一串允许的值,比如上面定义的星期
- 枚举可以单独定义在一个文件中,也可以嵌在其它
Java类中 - 枚举可以实现一个或多个接口(Interface)
- 可以定义新的变量
- 可以定义新的方法
- 可以定义根据具体枚举值而相异的类
API
| 方法名称 | 描述 |
|---|---|
| values() | 以数组形式返回枚举类型的所有成员 |
| valueOf() | 将普通字符串转换为枚举实例 |
| compareTo() | 比较两个枚举成员在定义时的顺序 |
| ordinal() | 获取枚举成员的索引位置 |
用法
- 常量
public enum week {
SUNDAY,
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY;
}
- switch
public class emumTest {
Week today = Week.SUNDAY;
public void method() {
Week week = null;
switch (today) {
case MONDAY:
week = Week.MONDAY;
break;
case TUESDAY:
week = Week.TUESDAY;
break;
case WEDNESDAY:
week = Week.WEDNESDAY;
break;
default:
break;
}
}
}
- 向枚举中添加新方法
public enum Week {
SUNDAY("星期日",1),
SATURDAY("星期六",2);
private String name;
private int index;
private Week(String name,int index){
this.name = name;
this.index = index;
}
// 普通方法
public static String getName(int index) {
for (Week c : Week.values()) {
if (c.getIndex() == index) {
return c.name;
}
}
return null;
}
//setget...
}
public class emumTest {
public static void main(String[] args) {
System.out.println(Week.SATURDAY); //SATURDAY
System.out.println(Week.SATURDAY.getName());//星期六
System.out.println(Week.SUNDAY);//SUNDAY
System.out.println(Week.getName(1));//星期日
}
}
- 覆盖枚举的方法 (重写toString)
@Override
public String toString() {
return this.name + "-" + this.index;
}
public class emumTest {
public static void main(String[] args) {
System.out.println(Week.SATURDAY); //星期六-2
System.out.println(Week.SATURDAY.getName());//星期六
System.out.println(Week.SUNDAY);//星期日-1
System.out.println(Week.getName(1));//星期日
}
}
- 实现接口
public interface Behaviour {
void print();
String getInfo();
}
enum Week2 implements Behaviour{
SUNDAY("星期日",1),
SATURDAY("星期六",2);// 成员变量
private String name;
private int index;
// 构造方法
private Week2(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);
}
}
System.out.println(Week2.SATURDAY.getInfo());//星期六
- 使用接口组织枚举
public interface Food {
enum Coffee implements Food{
BLACK_COFFEE,DECAF_COFFEE,LATTE,CAPPUCCINO
}
enum Dessert implements Food{
FRUIT, CAKE, GELATO
}
}
System.out.println(Food.Coffee.BLACK_COFFEE);//BLACK_COFFEE
好处
-
简化代码
见名知意
-
线程安全
第一次使用到的时候,虚拟机会对其进行初始化、类加载操作,这个过程是线程安全的
-
序列化安全
因为Java的序列化规定,对于enum类型的对象,在序列化的时候只是保存了一个名字,当再次进行反序列化的时候,它会根据这个名字到虚拟机中去找这个enum对象,这期间的writeObject,readObject等等一系列调用全部禁用,所以说枚举是序列化安全的。
注意
枚举的常量在作为方法参数传参时, 和普通字符串不一样, 只有方法的参数声明中使用枚举类型时, 才可以传参
常量有类型, 枚举也是一种类型, 使用时类型要一致