java中枚举的使用
文章目录
- 1 枚举
- 1.1 自定义类实现枚举
- 1.2 enum 关键字实现枚举
- 1.2.1 enum 关键字使用注意事项
- 1.2.2 枚举类 enum 常用方法说明
- (1) toString() 方法,返回当前对象名,子类可以重写。
- (2) name() 方法,返回当前对象名(常量名),子类中不能重写。
- (3) ordinal() 方法,返回当前对象的位置号,默认从0开始。
- (4) values() 方法,枚举中的一个特殊方法,在Enum 的 API 文档中也找不到这个方法。
- (5) valueOf() 方法,将字符串转换成枚举对象,要求字符串必须为已有的常量名,否则报异常!
- (6) compareTo() 方法,比较2个枚举常量,比较的是它们的编号。
- 1.2.3 enum 实现接口
1 枚举
枚举对应英文(enumeration, 简写 enum)。 枚举是一组常量的集合。 可以这里理解:枚举属于一种特殊的类,里面只包含一组有限的特定的对象。
枚举的2种实现方式:
- 自定义类实现枚举。
- 使用 enum 关键字实现枚举。
1.1 自定义类实现枚举
自定义类实现枚举按如下步骤进行:
- 不需要提供 setXX 方法,因为枚举对象值通常为只读。
- 对枚举对象/属性使用 final + static 共同修饰,实现底层优化。2者共同修饰,在使用时不会进行类的加载。
- 枚举对象名通常使用全部大写,符合常量的命名规范。
- 枚举对象根据需要,也可以有多个属性。
案例演示:
public class Test {
public static void main(String[] args) {
}
}
class Season {
private String name;
private String desc;//描述
//定义了,四个对象表示4个季节
//没有提供 setXX 方法,即不允许修改
public static final Season SPRING = new Season("春天", "温暖");
public static final Season WINTER = new Season("冬天", "寒冷");
public static final Season AUTUMN = new Season("秋天", "凉爽");
public static final Season SUMMER = new Season("夏天", "炎热");
//1.将构造器私有化,防止 new
//2.去掉 setXX 方法,防止属性被修改
//3.在 Season 内部,直接创建固定的对象
//4.优化,可以加入 final 修饰符
private Season(String name, String desc) {
this.name = name;
this.desc = desc;
}
//可以提供 getXX 方法
public String getName() {
return name;
}
public String getDesc() {
return desc;
}
@Override
public String toString() {
return "Season{" +
"name='" + name + '\' +
", desc='" + desc + '\' +
'}';
}
}
总结:进行自定义类实现枚举,有如下的特点:
- 构造器私有化
- 本类内部创建一组对象[四个季节 春夏秋冬]
- 对外暴露对象(通过为对象添加public final static修饰符)
- 可以提供get方法,但是不要提供set方法
1.2 enum 关键字实现枚举
由一个使用 enum 关键字的案例来进行体会:
public class Test {
public static void main(String[] args) {
System.out.println(Season2.AUTUMN);
System.out.println(Season2.SUMMER);
}
}
//使用 enum 关键字定义枚举类
enum Season2 {
//定义了四个对象, 固定.
//public static final Season SPRING = new Season("春天", "温暖");
//public static final Season WINTER = new Season("冬天", "寒冷");
//public static final Season AUTUMN = new Season("秋天", "凉爽");
//public static final Season SUMMER = new Season("夏天", "炎热");
//如果使用了enum 来实现枚举类
//1. 使用关键字 enum 替代 class
//2. public static final Season SPRING = new Season("春天", "温暖") //直接使用SPRING("春天", "温暖") 解读 常量名(实参列表)
//3. 如果有多个常量(对象), 使用 ,号间隔即可
//4. 如果使用enum 来实现枚举,要求将定义常量对象,写在最前面
//5. 如果我们使用的是无参构造器,创建常量对象,则可以省略 ()
SPRING("春天", "温暖"),WINTER("冬天", "寒冷"),
AUTUMN("秋天", "凉爽"),SUMMER("夏天", "炎热")/*,What*/;
private String name;
private String desc;
private Season2() {}
private Season2(String name, String desc) {
this.name = name;
this.desc = desc;
}
public String getName() {
return name;
}
public String getDesc() {
return desc;
}
@Override
publicStringtoString(){
return"Season{"+
"name='"+name+'\''+
",desc='"+desc+'\''+
'}';
}
}
1.2.1 enum 关键字使用注意事项
- 当我们使用 enum 关键字开发一个枚举类时,默认会继承 Enum 类,而且是一个 final 类,使用 javap 反编译指令进行验证。
(1) 进入编译后的类文件所在存储位置,使用 cmd 指令进入命令行窗口。
(2)使用 javap Season2.class
指令,对类文件进行反编译。
可以明显的,看出 enum Season2 定义的枚举类,默认继承了 Enum 类。
- 传统的
public static final Season2 SPRING = new Season("春天","温暖");
简化成了SPRING("春天","温暖")
,这里需要清楚的是,它调用的构造器是哪一个。 - 如果使用了无参构造器,创建枚举对象时,实参列表和小括号都可以省略不写。
- 当有多个枚举对象时,使用 逗号( , ) 间隔,最后有一个分号( ; )结尾。
- 枚举对象必须放在枚举类的行首。
1.2.2 枚举类 enum 常用方法说明
使用关键字 enum 时,会隐式的继承 Enum 类,这样我们就可以使用 Enum 类相关的方法。
Enum类的方法如下:
(1) toString() 方法,返回当前对象名,子类可以重写。
例如:
public class Test {
public static void main(String[] args) {
Week monday = Week.MONDAY;
System.out.println(monday.toString());
//输出 MONDAY
}
}
enum Week {
MONDAY;
}
(2) name() 方法,返回当前对象名(常量名),子类中不能重写。
例如:
public class Test {
public static void main(String[] args) {
Week monday = Week.MONDAY;
System.out.println(monday.name());
//输出 MONDAY
}
}
enum Week {
MONDAY;
}
(3) ordinal() 方法,返回当前对象的位置号,默认从0开始。
例如:
public class Test {
public static void main(String[] args) {
Week week = Week.TUESDAY;
System.out.println(week.ordinal());
//TUESDAY 在定义时在第二个位置,从0开始,所以为1
//输出 1
}
}
enum Week {
MONDAY,TUESDAY,WEDNESDAY;
}
(4) values() 方法,枚举中的一个特殊方法,在Enum 的 API 文档中也找不到这个方法。
通过上面的反编译后的信息可以看到有这个方法:
它的作用是:将枚举类中的所有枚举对象常量,转变为一个枚举类型的数组,元素下标即为枚举常量的声明位置,从0开始。
例如:
public class Test {
public static void main(String[] args) {
Week[] week = Week.values();
//此时,week 数组有3个元素
// week[0] = MONDAY
// week[1] = TUESDAY
// week[2] = WEDNESDAY
}
}
enum Week {
MONDAY,TUESDAY,WEDNESDAY;
}
(5) valueOf() 方法,将字符串转换成枚举对象,要求字符串必须为已有的常量名,否则报异常!
例如:
public class Test {
public static void main(String[] args) {
//执行流程
//1. 根据你输入的 "MONDAY" 到 Week 的枚举对象去查找
//2. 如果找到了,就返回,如果没有找到,就报错
Week week = Week.valueOf("MONDAY");
//易知,MONDAY 在Week中存在,且能找到
//即,week = Week.MONDAY;
}
}
enum Week {
MONDAY,TUESDAY,WEDNESDAY;
}
(6) compareTo() 方法,比较2个枚举常量,比较的是它们的编号。
public class Test {
public static void main(String[] args) {
int result;
result = Week.MONDAY.compareTo(Week.WEDNESDAY);
//即,MONDAY 在第一个,为0
// WEDNESDAY 在第三个,为2
//所以 Week.MONDAY.compareTo(Week.WEDNESDAY)
// 为,0 - 2 = -2
System.out.println(result);//输出 -2
}
}
enum Week {
MONDAY,TUESDAY,WEDNESDAY;
}
1.2.3 enum 实现接口
-
使用 enum 关键字后,就不能再继承其它类了,因为 enum 会隐式继承 Enum 类,而 java 是单继承机制。
-
枚举类和普通类一样,可以实现接口,语法如下:
enum 类名 implements 接口1, 接口2 {}
案例演示:
public class Test {
public static void main(String[] args) {
Week.MONDAY.say();
}
}
interface A {
void say();
}
enum Week implements A{
MONDAY,TUESDAY,WEDNESDAY;
@Override
public void say() {
System.out.println("枚举类实现了接口A的say()方法");
}
}