JavaSE5️⃣核心类 - 枚举(enum)

1、枚举

1.1、含义

维基百科

在数学和计算机科学理论中,一个集的枚举是指:

  1. 列出有穷序列集的所有成员的程序。
  2. 一种特定类型对象的计数。

这两种类型经常重叠,是一个被命名的整型常数的集合。

1.2、int 常量

在 Java 5 之前,可定义 int 常量来表示枚举。

示例:定义季节。

public class Season {
    public static final int SPRING = 0;
    public static final int SUMMER = 1;
    public static final int AUTUMN = 2;
    public static final int WINTER = 3;
}

class Main {
    public static void doSomething(int season){
        if (season == Season.SPRING) {
            // ...
        }
    }
}

存在问题

  1. 安全性:编译器无法检查传入值的合法性(类型、范围)。
  2. 可读性:int 常量的输出结果是数字,无法表示常量的特点。

2、enum

Java 5+

枚举(enumeration):表示一组预定义的常量

  1. 使用关键字 enum,定义不同的枚举类。
  2. 编译器能自动检查枚举类型、某个引用值是否属于枚举集合内。

2.1、语法

按以下顺序声明一个枚举类。

  1. 声明枚举类,可实现接口
  2. 声明成员变量(如果需要)。
  3. 声明构造方法(如果需要)。
  4. 声明枚举成员
    1. 使用 () 填写参数列表(若调用空参构造方法,可省略括号)。
    2. 使用 , 分隔多个枚举成员,使用 ; 结束常量声明。

示例

  1. 定义枚举类

    public enum Season {
        SPRING(0, "春天"),
        SUMMER(1, "夏天"),
        AUTUMN(2, "秋天"),
        WINTER(3, "冬天"),
        ;
    
        public final int order;
        public final String value;
    
        Season(int order, String value) {
            this.order = order;
            this.value = value;
        }
    }
    
  2. 编译后相当于

    public final class Season extends Enum {
        public static final Season SPRING = new Season(0, "春天");
        public static final Season SUMMER = new Season(1, "夏天");
        public static final Season AUTUMN = new Season(2, "秋天");
        public static final Season WINTER = new Season(3, "冬天");
    
        public final int order;
        public final String value;
    
        private Season(int order, String value) {
            this.order = order;
            this.value = value;
        }
    }
    

2.2、特点

2.2.1、成员变量

Enum 定义的 2 个成员变量

  1. name:枚举成员的名称
  2. ordinal:枚举成员的序号,即声明的位置顺序。
    1. 从 0 开始计数。
    2. 新增的枚举需要放在后面,避免影响前面枚举的序号。

2.2.2、引用类型

enum 的本质是 class,拥有类的特性。

  1. 继承:默认继承自 java.lang.Enum,无法被继承。
  2. 实现:可实现一个或多个接口。
  3. 成员结构:除了枚举常量,enum 可以定义类的其它结构。
    1. 构造方法(默认 private
      1. 私有化,避免外部实例化新的枚举类型
      2. 若无显式定义构造方法,默认会生成无参构造方法。
    2. 成员变量:建议 final,并通过构造器初始化。
    3. 成员方法等其它结构。

2.2.3、单实例

参考 👉 单例模式

  1. 每个实例在 JVM 中具有唯一实例
  2. 只能通过预定义的方式创建,无法 new 创建。

2.3、相关 API

2.3.1、获取实例

  1. values():以数组形式返回所有枚举成员实例

    Season[] seasons = Season.values();		// [SPRING, SUMMER, AUTUMN, WINTER]
    
  2. valueOf():通过 name 获取指定枚举实例

    1. Enum 的静态方法。

    2. 枚举类的静态方法。

      Season s1 = Enum.valueOf(Season.class, "SPRING");
      Season s2 = Season.valueOf("SPRING");
      

2.3.2、名称

  1. name():返回枚举成员的名称。

    String springName = Season.SPRING.name();	// SPRING
    
  2. toString():默认返回 name,可以重写以提高可读性。

    String springStr = Season.SPRING.toString();	// 默认 SPRING
    

使用 name() 获取名称,

使用 toString() 获取描述。

2.3.3、序号

  1. ordinal():返回枚举成员的序号。

    int o1 = Season.SPRING.ordinal();	// 0
    int o2 = Season.WINTER.ordinal();	// 3
    
  2. compareTo():比较枚举成员的序号之差。

    int dist = Season.SPRING.compareTo(Season.WINTER);	// -3
    

2.4、相关操作

2.4.1、比较

enum 成员具有唯一实例,可直接使用 == 比较

也可使用 equals()

public void doSomething(Season season) {
    if (season.equals(Season.SPRING)) {	// ok
    }

    if (season == Season.SPRING) {	// ok!
    } 
}

2.4.2、switch 枚举

随着 Java 5 引入 enum 类型,

switch 结构也支持判断枚举类型。

public void doSomething(Season season){
    switch(season) {
        case SPRING:
            // ...
            break;
        case SUMMER:
            // ...
            break;
        case AUTUMN:
            // ...
            break;
        case WINTER:
            // ...
            break;
        default:
            // ...
    }
}

原理:👉 编译期优化 1.7.2

  1. 生成一个合成类,包含一个成员变量(int[] 数组)。
  2. 数组元素与枚举成员的 ordinal 依次对应。
  3. switch 枚举等价转换成 switch ordinal
posted @ 2023-02-26 22:43  Jaywee  阅读(47)  评论(0编辑  收藏  举报

👇