Java 枚举

什么是枚举

Java 枚举是一种特殊的数据类型,它允许我们定义一组常量,并且可以在程序中使用这些常量。枚举常量是一组有意义的、不可变的值,通常用于表示某些特定的状态、类型或选项。在 Java 中,枚举是通过 enum 关键字来定义的。可以说,Java 枚举提供了一种更加优雅、类型安全和易于维护的方式来管理常量。

定义枚举类型

定义一个枚举类型需要使用 enum 关键字,语法如下:

enum EnumName {
  CONSTANT1,
  CONSTANT2,
  ...
}

其中,EnumName 是枚举类型的名称,CONSTANT1、CONSTANT2 等是枚举常量的名称。枚举常量必须是大写字母或下划线,并且按照惯例应该使用大写字母命名。枚举常量之间用逗号分隔,最后一个常量后面不需要加逗号。

例如,我们可以定义一个 Weekday 枚举类型:

public enum Weekday {
  MONDAY,
  TUESDAY,
  WEDNESDAY,
  THURSDAY,
  FRIDAY,
  SATURDAY,
  SUNDAY
}

使用枚举类型

创建一个枚举变量需要使用枚举类型中的常量。例如,我们可以创建一个 Weekday 类型的变量:

Weekday day = Weekday.MONDAY;

比较

在比较枚举变量时,可以使用 == 运算符。例如,我们可以比较 day 是否等于 MONDAY:

Weekday day = Weekday.MONDAY;
if (day == Weekday.MONDAY) {
    System.out.println("Today is Monday.");
}

枚举类型也可以用于 switch 比较。

Weekday monday = Weekday.MONDAY;
switch (monday){
    case MONDAY :{System.out.println("周一");break;}
    case SUNDAY :{System.out.println("周末");break;}
}
// 输出:周一

遍历

除了使用枚举常量外,我们还可以使用枚举类型的 values() 方法来获取所有的枚举常量:

Weekday[] weekdays = Weekday.values();
for (Weekday weekday : weekdays) {
  System.out.println(weekday);
}
// 输出:
// MONDAY
// TUESDAY
// WEDNESDAY
// THURSDAY
// FRIDAY
// SATURDAY
// SUNDAY

查询

使用 valueOf() 方法可以查找指定字符串名称的枚举常量。如果查找不到,会报 IllegalArgumentException。利用这个方法可以进行枚举值查找或者是否存在判断。

System.out.println(Weekday.valueOf("MONDAY"));
System.out.println(Weekday.valueOf("MONDAY1"));

输出:

MONDAY
Exception in thread "main" java.lang.IllegalArgumentException: No enum constant com.wdbyte.enum2.Weekday.MONDAY1
	at java.base/java.lang.Enum.valueOf(Enum.java:273)
	at com.wdbyte.enum2.Weekday.valueOf(Weekday.java:3)
	at com.wdbyte.enum2.WeekdayTest.main(WeekdayTest.java:19)

枚举类型的方法

枚举类型允许我们定义构造函数、方法和字段。例如,我们可以为 Weekday 枚举类型定义一个 name 自动,同时定义一个 getName 方法。因为在构造函数中也增加 name 参数,所以在定义枚举值时可以直接传入 name 信息,这里就是调用了构造函数。

enum Weekday {
  MONDAY("星期一"),
  TUESDAY("星期二"),
  WEDNESDAY("星期三"),
  THURSDAY("星期四"),
  FRIDAY("星期五"),
  SATURDAY("星期六"),
  SUNDAY("星期日");

  private final String name;

  Weekday(String name) {
    this.name = name;
  }

  public String getName() {
    return name;
  }
}

在上面的例子中,我们为每个枚举常量设置一个名称,并将其保存到 name 字段中。在方法 getName 中,我们返回枚举常量的名称。

枚举高级用法

下面的枚举的高级用法可能很少使用,许多使用了很久枚举的同学可能也不知道,其实这些高级用法一点都不奇怪,如果你把枚举就看做一个特殊写法的类,那么就都一目了然。

枚举实现接口

示例:定义接口。

package com.wdbyte.enum2;

/**
 * 形状接口
 */
public interface Shape {
    /**
     * 计算面积
     * @return
     */
    double getArea();
}

定义枚举:

package com.wdbyte.enum2;

/**
 * 矩形枚举类
 */
public enum Rectangle implements Shape {
    SMALL(3, 4),
    MEDIUM(4, 5),
    LARGE(5, 6);

    private int length;
    private int width;

    Rectangle(int length, int width) {
        this.length = length;
        this.width = width;
    }

    public double getArea() {
        return length * width;
    }
}

测试:

public static void main(String[] args) {
    Shape shape = Rectangle.LARGE;
    double shapeArea = shape.getArea();
    System.out.println(shapeArea); // 输出:30.0
}

枚举重载方法

枚举可以进行方法重载,可以实现很多功能,如实现加减乘法计算。

示例:

package com.wdbyte.enum2;

/**
 * 计算枚举类
 */
public enum Calc {
    // 加法
    PLUS {
        public int apply(int x, int y) {
            return x + y;
        }
    },
    // 减法
    MINUS {
        public int apply(int x, int y) {
            return x - y;
        }
    },
    // 乘法
    MULTIPLY {
        public int apply(int x, int y) {
            return x * y;
        }
    };
    public int apply(int x, int y){
        // todo
        return x + y;
    }
    public abstract int apply(int x, int y);
}

测试代码:

package com.wdbyte.enum2;

/**
 * @author https://www.wdbyte.com
 */
public class CalcTest {
    public static void main(String[] args) {
        // 加法
        int res = Calc.PLUS.apply(2, 3);
        System.out.println(res); // 5
        // 减法
        res = Calc.MINUS.apply(2, 3);
        System.out.println(res); // -1
        // 乘法
        res = Calc.MULTIPLY.apply(2, 3);
        System.out.println(res); // 6
    }
}

枚举抽象方法

抽象方法必须被子类实现,枚举类中的每个枚举值都是当前类型的一个实现,所以可以如普通方法重载一样进行抽象函数实现。

package com.wdbyte.enum2;

/**
 * 计算枚举类
 */
public enum Calc {
    // 加法
    PLUS {
        public int apply(int x, int y) {
            return x + y;
        }
    },
    // 减法
    MINUS {
        public int apply(int x, int y) {
            return x - y;
        }
    },
    // 乘法
    MULTIPLY {
        public int apply(int x, int y) {
            return x * y;
        }
    };
    public abstract int apply(int x, int y);
}

一如既往,文章中代码存放在 Github.com/niumoo/javaNotes.