Java 枚举类型(Enum)
Java 枚举是一个特殊的类,一般表示一组常量,比如一年的 4 个季节,一个年的 12 个月份,一个星期的 7 天,方向有东南西北等。
Java 枚举类使用 enum 关键字来定义,各个常量使用逗号 , 来分割。
- enum和class、interface的地位一样。
- 使用enum定义的枚举类默认继承了java.lang.Enum,而不是继承Object类。枚举类可以实现一个或多个接口,与普通类一样,实现接口的时候需要实现接口中定义的所有方法。
- 枚举类的所有实例都必须放在第一行展示,不需使用new 关键字,不需显式调用构造器。自动添加public static final修饰。
- 使用enum定义、非抽象的枚举类默认使用final修饰,不可以被继承。
- 枚举类的构造器只能是私有的。
- 枚举类内也可以定义属性和方法,可是是静态的和非静态的。枚举既可以包含具体方法,也可以包含抽象方法。 如果枚举类具有抽象方法,则枚举类的每个实例都必须实现它。
package meiju;
public enum D01 implements A {// 默认继承了java.lang.Enum
// 自动添加public static final修饰。所以是蓝色加粗斜体。
一月(1), 二月(2), 三月, 四月, 五月, 六月, 七月, 八月, 九月, 十月, 十一月, 十二月(12);// 所有实例都必须放在第一行展示,不需使用new 关键字
public static void main(String[] args) {// 枚举类内也可以定义属性和方法,可是是静态的和非静态的。
}
public int a;
// 写枚举类实例的时候,默认是调用了构造器的所以括号内有
private D01() {// 枚举类的构造器只能是私有的
}
private D01(int a) {// 这个构造器可以在 实例默认调用构造器时调用
}
public void aa() {
}
public void bb() {
}
}
interface A {
public void aa();
public void bb();
}
不同的枚举值提供不同的实现实例:
package meiju;
public enum D02 {
加{
public int jisuan(int X, int Y) {
return X+Y;
}
},减 {
public int jisuan(int X, int Y) {
return X-Y;
}
},乘 {
public int jisuan(int X, int Y) {
return X*Y;
}
},除{
public int jisuan(int X, int Y) {
return X/Y;
}
};
public abstract int jisuan(int a,int b);// 抽象方法,由不同的枚举值提供不同的实现枚举既可以包含具体方法,也可以包含抽象方法。 如果枚举类具有抽象方法,则枚举类的每个实例都必须实现它。
public static void main(String[] args) {
System.out.print(D02.加.jisuan(0,0));
System.out.print(D02.减.jisuan(10, 3));
System.out.print(D02.乘.jisuan(1, 1));
System.out.print(D02.除.jisuan(4, 2));
}
}
/*输出结果
*0712
*/
switch语句里的表达式可以是枚举值:
package meiju;
public class D03 {//switch语句的表达式可以是枚举值
public static D02 a;
public static void main(String[] args) {
a=D02.加;
switch(a) {
case 乘:
System.out.println("调用乘法");
break;
case 减:
break;
case 加:
System.out.println(D02.加.jisuan(3, 5));
System.out.println("调用加法");
break;
case 除:
break;
default:
break;
}
}
}
/*8
*调用加法
*/
什么时候使用枚举类?
有的时候一个类的对象是有限且固定的,这种情况下我们使用枚举类就比较方便。
为什么不用静态常量代替枚举类?
枚举类更加直观,类型安全。使用静态常量会有以下几个缺陷:
1. 类型不安全。若一个方法中要求传入季节这个参数,用常量的话,形参就是int类型,开发者传入任意类型的int类型值就行,但是如果是枚举类型的话,就只能传入枚举类中包含的对象。
2. 没有命名空间。开发者要在命名的时候以SEASON_开头,这样另外一个开发者再看这段代码的时候,才知道这常量分别代表季节。
values(), ordinal() 和 valueOf() 方法
enum 定义的枚举类默认继承了 java.lang.Enum 类,并实现了 java.lang.Seriablizable 和 java.lang.Comparable 两个接口。
values(), ordinal() 和 valueOf() 方法位于 java.lang.Enum 类中:
- values() 返回枚举类中所有的值。
- ordinal()方法可以找到每个枚举常量的索引,就像数组索引一样。
- valueOf()方法返回指定字符串值的枚举常量。
package meiju;
public class D04 {
enum color {
red, yellow, blue, white;
}
public static void main(String[] args) {
System.out.println(color.valueOf("red"));// 使用valueOf()返回指定字符串值的枚举常量 ,不存在的会报错 IllegalArgumentException
color[] arr = color.values();// 调用values返回枚举类中所有的值
for (color x : arr) {
System.out.println(x + " at index " + x.ordinal());// 调用ordinal方法找到每个常量的枚举索引,类似数组索引
}
System.out.println(color.red.toString());//枚举变量的toString()方法。该方法直接返回枚举定义枚举变量的字符串,比如MON就返回【”MON”】。
int a = color.red.compareTo(color.white);//实际上比较的是两个枚举变量的次序,返回两个次序相减后的结果.
System.out.println(a);
}
}
/*
red
red at index 0
yellow at index 1
blue at index 2
white at index 3
red
-3
*/