Java枚举类

发布 | 2024-08-05 | JAVA




枚举类型本质上也是一种类,只不过是这个类的对象是有限的、固定的几个,不能让
用户随意创建,它继承的是 java.lang.Enum类


😀 枚举类的实现


– 在 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);
      }
    }
    


    – 在 JDK5.0 之后
    Java 支持 enum 关键字来快速定义枚举类型。


    语法格式

    
    【修饰符】 enum 枚举类名{
    常量对象列表
    }
    
    【修饰符】 enum 枚举类名{
    常量对象列表;
    对象的实例变量列表;
    }
    

注意:枚举类的常量对象列表必须在枚举类的首行

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


    常用方法

    方法说明
    String toString()默认返回的是常量名(对象名),可以继续手动重写该方法
    static 枚举类型[] values()返回枚举类型的对象数组。该方法可以很方便地遍历所有的枚举值,是一个静态方法
    static 枚举类型 valueOf(String name)可以把一个字符串转为对应的枚举类对象。要求字符串必须是枚举类对象的“名字”。如不是,会有运行时异常:IllegalArgumentException
    String name()得到当前枚举常量的名称。建议优先使用 toString()
    int ordinal()回当前枚举常量的次序号,默认从 0 开始
public enum Month {
    /** 一月 */
    JANUARY("01"),
    /** 二月 */
    FEBRUARY("02"),
    /** 三月 */
    MARCH("03"),
    /** 四月 */
    APRIL("04"),
    /** 五月 */
    MAY("05"),
    /** 六月 */
    JUNE("06"),
    /** 七月 */
    JULY("07"),
    /** 八月 */
    AUGUST("08"),
    /** 九月 */
    SEPTEMBER("09"),
    /** 十月 */
    OCTOBER("10"),
    /** 十一月 */
    NOVEMBER("11"),
    /** 十二月 */
    DECEMBER("12");

    /** 月份描述 */
    private final String description;

    /**
     * 构造方法,初始化月份描述
     * @param description 月份描述
     */
    Month(String description) {
        this.description = description;
    }

    /**
     * 根据月份描述获取月份枚举
     * @param description 月份描述
     * @return 对应的月份枚举,找不到返回null
     */
    public static Month getMonth(String description) {
        for (Month month : Month.values()) {
            if (month.description.equals(description)) {
                return month;
            }
        }
        return null;
    }

    /**
     * 根据月份序号获取月份枚举
     * @param month 月份序号(1-12)
     * @return 对应的月份枚举
     */
    public static Month getMonth(int month) {
        return Month.values()[month - 1];
    }

    /**
     * 获取月份的天数
     * @param leapYear 是否为闰年
     * @return 月份的天数
     */
    public int length(boolean leapYear) {
        return switch (this) {
            case JANUARY, MARCH, MAY, JULY, AUGUST, OCTOBER, DECEMBER -> 31;
            case APRIL, JUNE, SEPTEMBER, NOVEMBER -> 30;
            default -> leapYear ? 29 : 28;
        };
    }

    /**
     * 获取月份的默认天数(非闰年)
     * @return 月份的默认天数
     */
    public int days() {
        return length(false);
    }

    /**
     * 重写toString方法,输出月份描述和天数
     * @return 月份描述和天数
     */
    @Override
    public String toString() {
        return "Month{" +
                "description='" + description + '\'' +
                ", days=" + days() +
                '}';
    }
}

标签
枚举

© 著作权归作者所有

本文由 趣代码Blog 创作,采用 知识共享署名4.0 国际许可协议进行许可,本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名。

评论关闭