美文网首页
enum 枚举

enum 枚举

作者: 敲代码的本愿 | 来源:发表于2016-12-16 12:26 被阅读20次

    enum (enumeration), 是 JDK 1.5 中引入的新特性,在 java.lang 包中。

    定义

    创建枚举类型使用 enum 关键字,创建的类型都是 java.lang.Enum(抽象类) 类的子类。枚举类型符合通用模式 Class Enum<E extends Enum<E>>E 表示枚举类型的名称。枚举类型的每一个值都将映射到 protected Enum(String name, int ordinal)构造函数中,在这里,每个值的名称都被转换成一个字符串,并且序数设置表示了此设置被创建的顺序。

    public enum Week{
        MON, TUE, WED, THU, FRI, SAT, SUN;
     } 
    
    // 内部调用了7次 Enum(String name, int ordinal):
    new Enum<EnumTest>("MON",0);
    new Enum<EnumTest>("TUE",1);
    new Enum<EnumTest>("WED",2);
        ... ...
    
    1. 枚举类是特殊的class,有构造器、方法和数据域,被final修饰,不可被继承;
    2. 枚举值MON, TUE...都是Week类型的静态常量(public static final 修饰),故通常全部大写。
    // 获取实例
    Week w = Week.MON; 
    

    使用

    一. 自定义方法、覆盖枚举的方法

    自定义方法时必须在enum实例序列最后添加分号。同时Java 要求必须先定义 enum 实例.

    enum Week {
        MON(2016, 12, 12), TUE(2016, 12, 13), WED(2016, 12, 14), THU(2016, 12, 15), 
        FRI(2016, 12, 16), SUN(2016, 12, 17), SUN(2016, 12, 18); 
    
        //自定义数据域 (get、set 封装)
        private int year; 
        private int mouth;
        private int day;
    
        // 构造枚举值
        private Week (int year, int mouth, int day){ 
            this.year = year;
            this.mouth = mouth;
            this.day = day; 
        }
    
        // 自定义方法
        public String getDate(int day) { 
            for (Week w : Week.values()) { // 遍历
                if (w.getDay() == day) { 
                    return toString();
                } 
            } 
            return null; 
        }
    
        //覆盖方法  
        @Override 
        public String toString() { 
             return w.year + "年" + w.mouth + "月" + w.day + "日" ;
        }  
    }
    

    注意:

    1. 构造器只在构造枚举值时被调用;
    2. 构造器只能私有private,不允许public修饰。保证了外部代码无法构造新枚举类的实例,因为枚举值是public static final的常量。 但枚举类的方法和数据域允许外部访问。
    // 错误写法
    Week week = new Week(2017, 1, 1);
    
    // 正确写法
    Week week = Week.MON;
    System.out.println(week.getDate());
    

    二. switch 操作

    public void change() {
    
        Week week = Week.WED;
        switch (week) { 
             case MON: 
                 week = Week.MON; 
                 break; 
             case TUE: 
                 week = Week.TUE; 
                 break; 
             case WED: 
                 week = Week.WED; 
                 break;
               ……
    }
    

    三. 实现接口

    枚举继承java.lang.Enum类。Java 不支持多继承,所以枚举对象不能继承其它类。

    public interface Behaviour { 
        void print(); 
        String getDayOfMouth(); 
    } 
    
    enum Week {
        MON(2016, 12, 12), TUE(2016, 12, 13), WED(2016, 12, 14), THU(2016, 12, 15), 
        FRI(2016, 12, 16), SUN(2016, 12, 17), SUN(2016, 12, 18); 
    
        // 成员变量 (get、set 封装)
        private int year; 
        private int mouth;
        private int day;
    
        // 构造方法
        private Week (int year, int mouth, int day){ 
            this.year = year;
            this.mouth = mouth;
            this.day = day; 
        }
    
        // 接口方法
        @Override
        public String getDayOfMouth(int day) { 
            return this.day;
        }
    
        // 接口方法
        @Override 
        public String print() { 
            System.out.println(w.year + "年" + w.mouth + "月" + w.day + "日"); 
        }  
    

    四. 接口组织枚举

    public interface Animal { 
    
        enum Water implements Animal { 
            SHARK, DOLPHIN, WHALE
        } 
    
        enum Land implements Animal { 
            DOG, CAT, PIG, WOLF, TIGER
        } 
    } 
    

    五. 方法

    继承于Enum的方法。

    1. int compareTo(E o)
      比较此枚举与指定对象的顺序(Enum实现了java.lang.Comparable接口)。返回两个枚举值的顺序之差。枚举必须属于同一个枚举类,否则抛出ClassCastException()异常。
    // MON, TUE, WED, THU, FRI, SUN, SUN
    Week.MON.compareTo(Week.WED);  // 结果 -2
    Week.WED.compareTo(Week.MON);  // 结果 2
    
    1. final boolean equals(Object other)
      比较两个枚举类对象的引用。
    2. Class<E> getDeclaringClass()
      返回与此枚举常量的枚举类型相对应的 Class 对象。
    Week week = Week.MON;
    System.out.println(week.getDeclaringClass().getName());
    // 输出结果:com.enumtest.test.Week;
    
    1. String name()
      返回此枚举常量的名称,在其枚举声明中对其进行声明。
    2. int ordinal()
      返回枚举常量在枚举类中的次序(初始常量序数为 0)。
    Week.MON.ordinal();  // 结果 0
    Week.WED.ordinal();  // 结果 2
    
    1. String toString()
      返回枚举常量的名称。
    Week w = Week.MON;
    System.out.println(w);//返回结果: MON
    
    1. static <T extends Enum<T>> T valueOf(Class<T> enumType, String name)
      返回带指定名称的指定枚举类型的枚举常量,与toString()方法相对应。
    Week.valueOf("MON");  // 结果 Week.MON
    
    1. values()
      静态方法,返回一个包含全部枚举值的数组。
    Week weeks = Week.values();
    for(Week w:weeks){
        System.out.print(w + ",");
    }
    //返回结果:MON, TUE, WED, THU, FRI, SUN, SUN
    

    五. 枚举集合

    java.util.EnumSet:保证集合中的元素不重复。
    java.util.EnumMapkeyenum类型,value可以是任意类型。

    // EnumSet的使用
    EnumSet<Week> weekSet = EnumSet.allOf(Week.class);
    for (Week w : weekSet) {
        System.out.println(w);
    }
    
    // EnumMap的使用
    EnumMap<Week, String> weekMap = new EnumMap(Week.class);
    weekMap.put(Week.MON, "星期一");
    weekMap.put(Week.TUE, "星期二");
    // ... ...
    for (Iterator<Entry<Week, String>> iter = weekMap.entrySet().iterator(); 
        iter.hasNext();) {
            Entry<Week, String> entry = iter.next();
            System.out.println(entry.getKey().name() + ":" + entry.getValue());
    }
    

    原理

    enum 的语法结构和 class 的不同,但编译器编译之后生成一个class文件。经反编译,可知该class文件生成了一个继承java.lang.Enum<E>的类。

    public class com.dev.test.Week extends java.lang.Enum{
        public static final com.dev.test.Week MON;
        public static final com.dev.test.Week TUE;
        public static final com.dev.test.Week WED;
        public static final com.dev.test.Week THU;
        public static final com.dev.test.Week FRI;
        public static final com.dev.test.Week SAT;
        public static final com.dev.test.Week SUN;
        static {};
        public int getValue();
        public boolean isRest();
        public static com.dev.test.Week[] values();
        public static com.dev.test.Week valueOf(java.lang.String);
        com.dev.test.Week(java.lang.String, int, int, com.dev.test.Week);
    }
    

    相关文章

      网友评论

          本文标题:enum 枚举

          本文链接:https://www.haomeiwen.com/subject/qiggmttx.html