1 枚举
枚举对应英文(enumeration, 简写 enum)。 枚举是一组常量的集合。 可以这里理解:枚举属于一种特殊的类,里面只包含一组有限的特定的对象。
枚举的2种实现方式:
1.1 自定义类实现枚举
自定义类实现枚举按如下步骤进行:
- 不需要提供 setXX 方法,因为枚举对象值通常为只读。
- 对枚举对象/属性使用 final + static 共同修饰,实现底层优化。2者共同修饰,在使用时不会进行类的加载。
- 枚举对象名通常使用全部大写,符合常量的命名规范。
- 枚举对象根据需要,也可以有多个属性。
案例演示:
java">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;}@Overridepublic String toString() {return "Season{" +"name='" + name + '\' +", desc='" + desc + '\' +'}';}}
总结:进行自定义类实现枚举,有如下的特点:
- 构造器私有化
- 本类内部创建一组对象[四个季节 春夏秋冬]
- 对外暴露对象(通过为对象添加public final static修饰符)
- 可以提供get方法,但是不要提供set方法
enum__76">1.2 enum 关键字实现枚举
由一个使用 enum 关键字的案例来进行体会:
java">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;}@OverridepublicStringtoString(){return"Season{"+"name='"+name+'\''+",desc='"+desc+'\''+'}';}
}
enum__133">1.2.1 enum 关键字使用注意事项
(1) 进入编译后的类文件所在存储位置,使用 cmd 指令进入命令行窗口。
(2)使用 javap Season2.class
指令,对类文件进行反编译。
可以明显的,看出 enum Season2 定义的枚举类,默认继承了 Enum 类。
- 传统的
public static final Season2 SPRING = new Season("春天","温暖");
简化成了SPRING("春天","温暖")
,这里需要清楚的是,它调用的构造器是哪一个。 - 如果使用了无参构造器,创建枚举对象时,实参列表和小括号都可以省略不写。
- 当有多个枚举对象时,使用 逗号( , ) 间隔,最后有一个分号( ; )结尾。
- 枚举对象必须放在枚举类的行首。
enum__155">1.2.2 枚举类 enum 常用方法说明
使用关键字 enum 时,会隐式的继承 Enum 类,这样我们就可以使用 Enum 类相关的方法。
Enum类的方法如下:
(1) toString() 方法,返回当前对象名,子类可以重写。
例如:
java">public class Test {public static void main(String[] args) {Week monday = Week.MONDAY;System.out.println(monday.toString());//输出 MONDAY}
}
enum Week {MONDAY;
}
(2) name() 方法,返回当前对象名(常量名),子类中不能重写。
例如:
java">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开始。
例如:
java">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开始。
例如:
java">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() 方法,将字符串转换成枚举对象,要求字符串必须为已有的常量名,否则报异常!
例如:
java">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个枚举常量,比较的是它们的编号。
java">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 = -2System.out.println(result);//输出 -2}
}
enum Week {MONDAY,TUESDAY,WEDNESDAY;
}
enum__303">1.2.3 enum 实现接口
案例演示:
java">public class Test {public static void main(String[] args) {Week.MONDAY.say();}
}
interface A {void say();
}
enum Week implements A{MONDAY,TUESDAY,WEDNESDAY;@Overridepublic void say() {System.out.println("枚举类实现了接口A的say()方法");}
}