9.1 概述
- 枚举类型本质上也是一种类,只不过是这个类的对象是有限的、固定的几个,不能让用户随意创建。
- 枚举类的例子举不胜举:
星期
:Monday(星期一)......Sunday(星期天)性别
:Man(男)、Woman(女)月份
:January(1月)......December(12月)季节
:Spring(春节)......Winter(冬天)三原色
:red(红色)、green(绿色)、blue(蓝色)支付方式
:Cash(现金)、WeChatPay(微信)、Alipay(支付宝)、BankCard(银行卡)、CreditCard(信用卡)就职状态
:Busy(忙碌)、Free(空闲)、Vocation(休假)、Dimission(离职)订单状态
:Nonpayment(未付款)、Paid(已付款)、Fulfilled(已配货)、Delivered(已发货)、Checked(已确认收货)、Return(退货)、Exchange(换货)、Cancel(取消)线程状态
:创建、就绪、运行、阻塞、死亡
- 若枚举只有一个对象, 则可以作为一种单例模式的实现方式。
- 枚举类的实现:
- 在JDK5.0 之前,需要程序员自定义枚举类型。
- 在JDK5.0 之后,Java支持
enum
关键字来快速定义枚举类型。
9.2 定义枚举类(JDK5.0 之前)
在JDK5.0 之前如何声明枚举类呢?
私有化
类的构造器,保证不能在类的外部创建其对象- 在类的内部创建枚举类的实例。声明为:
public static final
,对外暴露这些常量对象 - 对象如果有
实例变量
,应该声明为private final
(建议,不是必须),并在构造器中初始化
示例代码:
class Season{
private final String SEASONNAME;//季节的名称
private final String SEASONDESC;//季节的描述
private Season(String seasonName,String seasonDesc){
this.SEASONNAME = seasonName;
this.SEASONDESC = seasonDesc;
}
public static final Season SPRING = new Season("春天", "春暖花开");
public static final Season SUMMER = new Season("夏天", "夏日炎炎");
public static final Season AUTUMN = new Season("秋天", "秋高气爽");
public static final Season WINTER = new Season("冬天", "白雪皑皑");
@Override
public String toString() {
return "Season{" +
"SEASONNAME='" + SEASONNAME + '\'' +
", SEASONDESC='" + SEASONDESC + '\'' +
'}';
}
}
class SeasonTest{
public static void main(String[] args) {
System.out.println(Season.AUTUMN);
}
}
9.3 定义枚举类(JDK5.0 之后)
9.3.1 enum关键字声明枚举
【修饰符】 enum 枚举类名{ 常量对象列表 } 【修饰符】 enum 枚举类名{ 常量对象列表; 对象的实例变量列表; }
举例1:
package com.atguigu.enumeration;
public enum Week {
MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY;
}
public class TestEnum {
public static void main(String[] args) {
Season spring = Season.SPRING;
System.out.println(spring);
}
}
9.3.2 enum方式定义的要求和特点
- 枚举类的常量对象列表必须在枚举类的首行,因为是常量,所以建议大写。
- 列出的实例系统会自动添加 public static final 修饰。
- 如果常量对象列表后面没有其他代码,那么“;”可以省略,否则不可以省略“;”。
- 编译器给枚举类默认提供的是private的无参构造,如果枚举类需要的是无参构造,就不需要声明,写常量对象列表时也不用加参数
- 如果枚举类需要的是有参构造,需要手动定义,有参构造的private可以省略,调用有参构造的方法就是在常量对象名后面加(实参列表)就可以。
- 枚举类默认继承的是java.lang.Enum类,因此不能再继承其他的类型。
- JDK5.0 之后switch,提供支持枚举类型,case后面可以写枚举常量名,无需添加枚举类作为限定。
举例2:
public enum SeasonEnum {
SPRING("春天","春风又绿江南岸"),
SUMMER("夏天","映日荷花别样红"),
AUTUMN("秋天","秋水共长天一色"),
WINTER("冬天","窗含西岭千秋雪");
private final String seasonName;
private final String seasonDesc;
private SeasonEnum(String seasonName, String seasonDesc) {
this.seasonName = seasonName;
this.seasonDesc = seasonDesc;
}
public String getSeasonName() {
return seasonName;
}
public String getSeasonDesc() {
return seasonDesc;
}
}
举例3:
package com.atguigu.enumeration;
public enum Week {
MONDAY("星期一"),
TUESDAY("星期二"),
WEDNESDAY("星期三"),
THURSDAY("星期四"),
FRIDAY("星期五"),
SATURDAY("星期六"),
SUNDAY("星期日");
private final String description;
private Week(String description){
this.description = description;
}
@Override
public String toString() {
return super.toString() +":"+ description;
}
}
package com.atguigu.enumeration;
public class TestWeek {
public static void main(String[] args) {
Week week = Week.MONDAY;
System.out.println(week);
switch (week){
case MONDAY:
System.out.println("怀念周末,困意很浓");break;
case TUESDAY:
System.out.println("进入学习状态");break;
case WEDNESDAY:
System.out.println("死撑");break;
case THURSDAY:
System.out.println("小放松");break;
case FRIDAY:
System.out.println("又信心满满");break;
case SATURDAY:
System.out.println("开始盼周末,无心学习");break;
case SUNDAY:
System.out.println("一觉到下午");break;
}
}
}
经验之谈:
开发中,当需要定义一组常量时,强烈建议使用枚举类。
9.4 enum中常用方法
String toString(): 默认返回的是常量名(对象名),可以继续手动重写该方法! static 枚举类型[] values():返回枚举类型的对象数组。该方法可以很方便地遍历所有的枚举值,是一个静态方法 static 枚举类型 valueOf(String name):可以把一个字符串转为对应的枚举类对象。要求字符串必须是枚举类对象的“名字”。如不是,会有运行时异常:IllegalArgumentException。 String name():得到当前枚举常量的名称。建议优先使用toString()。 int ordinal():返回当前枚举常量的次序号,默认从0开始
举例:
package com.atguigu.enumeration;
import java.util.Scanner;
public class TestEnumMethod {
public static void main(String[] args) {
//values()
Week[] values = Week.values();
for (int i = 0; i < values.length; i++) {
//ordinal()、name()
System.out.println((values[i].ordinal()+1) + "->" + values[i].name());
}
System.out.println("------------------------");
Scanner input = new Scanner(System.in);
System.out.print("请输入星期值:");
int weekValue = input.nextInt();
Week week = values[weekValue-1];
//toString()
System.out.println(week);
System.out.print("请输入星期名:");
String weekName = input.next();
//valueOf()
week = Week.valueOf(weekName);
System.out.println(week);
input.close();
}
}
9.5 实现接口的枚举类
- 和普通 Java 类一样,枚举类可以实现一个或多个接口
- 若每个枚举值在调用实现的接口方法呈现相同的行为方式,则只要统一实现该方法即可。
- 若需要每个枚举值在调用实现的接口方法呈现出不同的行为方式,则可以让每个枚举值分别来实现该方法
语法:
//1、枚举类可以像普通的类一样,实现接口,并且可以多个,但要求必须实现里面所有的抽象方法!
enum A implements 接口1,接口2{
//抽象方法的实现
}
//2、如果枚举类的常量可以继续重写抽象方法!
enum A implements 接口1,接口2{
常量名1(参数){
//抽象方法的实现或重写
},
常量名2(参数){
//抽象方法的实现或重写
},
//...
}
举例:
interface Info{
void show();
}
//使用enum关键字定义枚举类
enum Season1 implements Info{
//1. 创建枚举类中的对象,声明在enum枚举类的首位
SPRING("春天","春暖花开"){
public void show(){
System.out.println("春天在哪里?");
}
},
SUMMER("夏天","夏日炎炎"){
public void show(){
System.out.println("宁静的夏天");
}
},
AUTUMN("秋天","秋高气爽"){
public void show(){
System.out.println("秋天是用来分手的季节");
}
},
WINTER("冬天","白雪皑皑"){
public void show(){
System.out.println("2002年的第一场雪");
}
};
//2. 声明每个对象拥有的属性:private final修饰
private final String SEASON_NAME;
private final String SEASON_DESC;
//3. 私有化类的构造器
private Season1(String seasonName,String seasonDesc){
this.SEASON_NAME = seasonName;
this.SEASON_DESC = seasonDesc;
}
public String getSEASON_NAME() {
return SEASON_NAME;
}
public String getSEASON_DESC() {
return SEASON_DESC;
}
}
个人思考总结:
Java枚举类(Enum)是一种特殊的数据类型,用于表示一组常量值。枚举类可以帮助程序员更清晰地表示有限的、预定义的选项,提高代码的可读性和可维护性。
- 枚举类的定义:枚举类通过关键字
enum
来定义。它们在Java中是一种特殊的类,可以包含字段和方法。 - 预定义常量:枚举类允许在一个地方列出所有相关的常量。这些常量在枚举类中是唯一的,并且可以通过枚举类型的名称来访问。
enum Day { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY }
- 类型安全性:枚举类提供了类型安全性,因为它们只能包含定义的常量。这可以避免使用不正确的值。
- 可读性:枚举类的常量通常使用大写字母,这有助于提高代码的可读性,因为它们在代码中很容易识别。
- 枚举方法:可以向枚举类添加方法,这些方法可以与枚举常量一起工作。例如,可以在枚举类中添加一个方法来获取常量的描述。
enum Color { RED("红色"), GREEN("绿色"), BLUE("蓝色"); private String description; Color(String description) { this.description = description; } public String getDescription() { return description; } }
- 枚举的迭代:可以使用
values()
方法遍历枚举的所有常量,这对于循环处理枚举常量非常有用。for (Day day : Day.values()) { System.out.println(day); }
- switch语句的优势:枚举类常常用于替代复杂的if-else或switch语句,使代码更加清晰和易于维护。
switch (day) { case MONDAY: // Do something for Monday break; case TUESDAY: // Do something for Tuesday break; // ... }
- 枚举的内部实现:Java枚举类的内部实现通常是通过类似单例模式的方式实现的,确保每个常量只有一个实例。