Java 枚举类

逆流者 2020年07月14日 47次浏览

enum 关键字是JDK1.5时新增的,那1.5之前是怎么创建枚举类的呢?

自定义枚举类

创建自定义枚举类之前,我们先说下枚举类有哪些特性:

  • 枚举动类对象的属性不应允许被改动, 应该使用 private final修饰
  • 枚举类的使用 private final 修饰的属性应为其赋值,比如使用构造器赋值
  • 若枚举类显式的定义了带参数的构造器, 则在列出枚举值时也必须对应的传入参数

代码示例:

public class SeasonTest {

    public static void main(String[] args) {
        Season spring = Season.SPRING;
        Season summer = Season.SUMMER;
        Season autumn = Season.AUTUMN;
        Season winter = Season.WINTER;
        System.out.println(spring);
        System.out.println(summer);
        System.out.println(autumn);
        System.out.println(winter);
    }

}

/**
 * 自定义枚举类
 */
class Season{

    /**
     * 1.声明Season对象的属性:private final修饰
     */
    private final String seasonCode;
    private final String seasonName;

    /**
     * 2.私有化类的构造器,并给对象属性赋值
     */
    private Season(String seasonCode, String seasonName) {
        this.seasonCode = seasonCode;
        this.seasonName = seasonName;
    }

    /**
     * 3.提供当前枚举类的多个对象:public static final的
     */
    public static final Season SPRING = new Season("spring","春天");
    public static final Season SUMMER = new Season("summer","夏天");
    public static final Season AUTUMN = new Season("autumn","秋天");
    public static final Season WINTER = new Season("winter","冬天");

    /**
     * 4. 获取枚举类对象的属性
     */
    public String getSeasonCode() {
        return seasonCode;
    }
    public String getSeasonName() {
        return seasonName;
    }

    /**
     * 5. 提供toString()
     */
    @Override
    public String toString() {
        return "Season{" +
                "seasonCode='" + seasonCode + '\'' +
                ", seasonName='" + seasonName + '\'' +
                '}';
    }
}

使用enum定义枚举类

  • 使用 enum 定义的枚举类默认继承了java.lang.Enum类,因此不能再继承其他类
  • 枚举类的构造器只能使用 private 权限修饰符
  • 枚举类的所有实例必须在枚举类中显式列出(,分隔 ;结尾)。列出的实例系统会自动添加 public static final 修饰
  • 必须在枚举类的第一行声明枚举类对象
  • JDK 1.5 中可以在 switch 表达式中使用Enum定义的枚举类的对象作为表达式, case 子句可以直接使用枚举值的名字, 无需添加枚举类作为限定。

代码示例:

public class SeasonTest2 {

    public static void main(String[] args) {
        Season2 spring = Season2.SPRING;
        Season2 summer = Season2.SUMMER;
        Season2 autumn = Season2.AUTUMN;
        Season2 winter = Season2.WINTER;
        System.out.print(spring + " ");
        System.out.print(summer + " ");
        System.out.print(autumn + " ");
        System.out.print(winter + " ");
    }

}

/**
 * 使用enum关键字枚举类
 */
enum Season2 {

    /**
     * 1.提供当前枚举类的对象,多个对象之间用","隔开,末尾对象";"结束
     */
    SPRING("spring", "春天"),
    SUMMER("summer", "夏天"),
    AUTUMN("autumn", "秋天"),
    WINTER("winter", "冬天");

    /**
     * 2.声明Season对象的属性:private final修饰
     */
    private final String seasonCode;
    private final String seasonName;

    /**
     * 3.私有化类的构造器,并给对象属性赋值
     */
    private Season2(String seasonCode, String seasonName) {
        this.seasonCode = seasonCode;
        this.seasonName = seasonName;
    }

    /**
     * 4. 获取枚举类对象的属性
     */
    public String getSeasonCode() {
        return seasonCode;
    }

    public String getSeasonName() {
        return seasonName;
    }

}

测试结果:
SPRING SUMMER AUTUMN WINTER

看使用enum定义枚举类 定义Season2 中没有提供toString方法,看打印结果并不是打印的对象的哈希值,这说明枚举类的父类不是Object;

那使用enum定义的枚举类 父类是什么?
可以使用System.out.println(spring.getClass().getSuperclass());进行打印出来,结果为:class java.lang.Enum

Enum 类的主要方法

方法名描述
valueOf(Class<T> enumType, String name)传递枚举类型的Class对象和枚举常量名称参数,得到与参数匹配的枚举常量, name错误会抛IllegalArgumentException异常
toString()返回常量名称
equals(Object other)枚举类型可以直接使用“==”来比较是否相等,equals方法也是使用的“==”
hashCode()Enum 实现了hashCode()方法和equals保持一致,都是不可变的
getDeclaringClass()得到枚举常量所属枚举类型的Class对象,可用来判断两个枚举常量是否属于同一个枚举类型
name()得到当前枚举常量的名称,建议使用toString()方法
ordinal()当前枚举常量的次序
compareTo(E o)枚举实现了Comparable接口,比较的是枚举常量的次序(按照声明的顺序排列,从0开始)
clone()枚举类型不能Clone,会throw new CloneNotSupportedException()

实现接口的枚举类

  • 和普通 Java 类一样,枚举类可以实现一个或多个接口
  • 若每个枚举值在调用实现的接口方法呈现相同的行为方式,则只要统一实现该方法即可。
  • 若需要每个枚举值在调用实现的接口方法呈现出不同的行为方式, 则可以让每个枚举值分别来实现该方法

代码示例:

public class EnumTest {

    public static void main(String[] args) {
        Size small = Size.SMALL;
        System.out.println(small.getSizeInfo()); // 我是一个尺寸枚举类
        Size medium = Size.MEDIUM;
        System.out.println(medium.getSizeInfo()); // 我是 M 号
    }
}

interface SizeInfoInterface {
    String getSizeInfo();
}

enum Size implements SizeInfoInterface {

    SMALL("S"),
    MEDIUM("M") {
        /**
         * 若枚举值有不同的行为方式,可以自己实现接口的方法
         */
        @Override
        public String getSizeInfo() {
            return "我是 M 号";
        }
    },
    LARGE("L"),
    EXTRA_LARGE("XL");

    private String abbreviation;

    private Size(String abbreviation) {
        this.abbreviation = abbreviation;
    }

    public String getAbbreviation() {
        return abbreviation;
    }

    /**
     * 所有的枚举值都有相同的行为方式,可以统一实现接口的方法
     */
    @Override
    public String getSizeInfo() {
        return "我是一个尺寸枚举类";
    }
}