枚举类

101 阅读3分钟

枚举类

概念:枚举是一种特殊的类,里面只包含一组有限的特定的对象

自定义枚举

// 案例:创建春夏秋冬四个季节
public class EnumClass01 {
    public static void main(String[] args) {
        System.out.println(EnumDemo.WINTER);
        System.out.println(EnumDemo.SUMMER);
        System.out.println(EnumDemo.AUTUMN);
        System.out.println(EnumDemo.SPRING.toString());
    }
}
/*
 * 自定义枚举 (枚举对象名通常为大写字母)
 * 1)构造器私有化 => 外部不能创建对象
 * 2)去掉setXxx方法 => 外部不能修改属性
 * 3)直接创建固定的对象 => 枚举的特定用法
 * 4)可以使用 final static 修饰符优化 => 防止类初始化的时候加载对象
 * 5)可以提供get方法,重写toString方法用来输出
 */
class EnumDemo{
    private String seasonName;
    private String seasonFeature;
​
    public String getSeasonFeature() {
        return seasonFeature;
    }
​
    public String getSeasonName() {
        return seasonName;
    }
​
    //构造器
    private EnumDemo(String seasonName,String seasonFeature){
        this.seasonName = seasonName;
        this.seasonFeature = seasonFeature;
    }
    // 创建枚举对象
    final static EnumDemo SPRING = new EnumDemo("春天","温暖");
    final static EnumDemo SUMMER = new EnumDemo("夏天","炎热");
    final static EnumDemo AUTUMN = new EnumDemo("秋天","凉爽");
    final static EnumDemo WINTER = new EnumDemo("冬天","寒冷");
​
    @Override
    public String toString() {
        return "["+getSeasonName()+"--->"+getSeasonFeature()+"]";
    }
}

enum关键字实现枚举

public class EnumClass02 {
    public static void main(String[] args) {
        System.out.println(Session.AUTUMN); // [秋天--->凉爽]
    }
}
/*
 * 使用enum关键字来实现枚举
 * 1.当我们使用enum关键字开发一个枚举类时,默认会继承Enum类  java.lang.Enum<com.Al_tair.enum_.Session>
 * 反编译javap Session.class:
 * final class com.Al_tair.enum_.Session extends java.lang.Enum<com.Al_tair.enum_.Session> {
 *   public static final com.Al_tair.enum_.Session SPRING;
 *   public static final com.Al_tair.enum_.Session SUMMER;
 *   public static final com.Al_tair.enum_.Session AUTUMN;
 *   public static final com.Al_tair.enum_.Session WINTER;
 *   public static com.Al_tair.enum_.Session[] values();  // 隐藏
 *   public static com.Al_tair.enum_.Session valueOf(java.lang.String); 
 *   public java.lang.String getSeasonFeature();
 *   public java.lang.String getSeasonName();
 *   public java.lang.String toString();
 *   static {};
 * }
 */// Enum枚举类:使用关键字enum替代class
// 用enum关键字后,就不能在继承其他类了,因为会隐式继承Enum类(如上反编译文件),但是仍然是类,所以可以实现接口
enum Session{
    
    // 格式: 形式常量名(实参列表)
    // 如果有多个常量对象使用逗号间隔;并且要将定义常量对象写在最前面
    SPRING("春天","温暖"),
    SUMMER("夏天","炎热"),
    AUTUMN("秋天","凉爽"),
    // 如果我们是使用无参构造器的时候,创建常量对象可以省略括号
    WINTER;
    
    private String seasonName;
    private String seasonFeature;
    
    // 构造器
    Session() {}
    private Session(String seasonName,String seasonFeature){
        this.seasonName = seasonName;
        this.seasonFeature = seasonFeature;
    }
​
    public String getSeasonFeature() {
        return seasonFeature;
    }
    public String getSeasonName() {
        return seasonName;
    }
​
    @Override
    public String toString() {
        return "["+getSeasonName()+"--->"+getSeasonFeature()+"]";
    }
}

枚举常用方法

image-20220221102947758

 // 测试枚举常用方法
enum Week{
    MONDAY("星期一"),TUESDAY("星期二"),WEDNESDAY("星期三"),THURSDAY("星期四"),FRIDAY("星期五"),SATURDAY("星期六"),SUNDAY("星期日");
​
    private String WeekName;
​
    private Week(String WeekName) {
        this.WeekName = WeekName;
    }
}
​
class testMethod{
    public static void main(String[] args) {
        Week f = Week.FRIDAY;
        /*
            name() 默认获得父类Enum重写的toString()的方法;如果枚举类有重写toString()方法
             public String toString() {
                return name; // 返回对象名
            }
        */
        System.out.println(f.toString()); // FRIDAY
        System.out.println(f.toString() == f.name()); // true
​
        // ordinal() 返回此枚举常量的序数(它在其枚举声明中的位置,其中初始常量的序数为0)
        System.out.println(f.ordinal()); // 4
​
        // values();  // 隐藏,Enum类中无法查看 本质: 包含所有常量对象的数组
        // 实现效果: MONDAY  TUESDAY  WEDNESDAY  THURSDAY  FRIDAY  SATURDAY  SUNDAY
        for (int i = 0; i < Week.values().length; i++) {
            System.out.print(Week.values()[i]+"  ");
        }
​
        /* 
         * valueOf()方法 将字符串转换成枚举对象,要求字符串必须为已有的常量对象名,否则会报错
         * 源码如下
         *     public static <T extends Enum<T>> T valueOf(Class<T> enumType,String name) {
         *         T result = enumType.enumConstantDirectory().get(name);
         *         if (result != null) return result;
         *         if (name == null) throw new NullPointerException("Name is null");
         *         throw new IllegalArgumentException("No enum constant " +
         *                      enumType.getCanonicalName() + "." + name);
         *     }
         */
        Week m = Week.valueOf("MONDAY");
        System.out.println(m.toString()); // MONDAY
​
        /*
         * compareTo()方法:比较两个枚举常量对象序号,返回两个枚举常量序号(ordinal)差
         *     public final int compareTo(E o) {
         *         Enum<?> other = (Enum<?>)o;
         *         Enum<E> self = this;
         *         if (self.getClass() != other.getClass() && // optimization
         *             self.getDeclaringClass() != other.getDeclaringClass())
         *             throw new ClassCastException();
         *         return self.ordinal - other.ordinal; // 比较编号
         *     }
         */
        System.out.println(m.compareTo(f)); // -4
    }
}