枚举类

枚举类

使用场景:一个类的对象固定且有限(一般用来定义返回码、状态码)

产生原因:有明确的意义,固定且不能被更改(比static final设定强而且安全)

定义:使用 enum关键字,跟定义一个类相同,枚举类是一种特殊的类。第一行定义的是实例,使用逗号分隔。

public enum EnumDemo1 {
    SPRING,SUMMER,WINTER;
}

特征

  1. 父类是java.lang.Enum类,不能继承其他类,间接实现了java.lang.Serializable和java.lang.Comparable接口
  2. 定义的非抽象枚举类,默认是final类,其定义的实例对象也均是public static final
  3. 其构造器必须是private,如果没有显示指定默认也是private
  4. 其所有实例必须在第一行显示指定,否则该枚举类永远不能产生实例

遍历枚举实例

// 枚举类默认提供了一个values()方法,可以用来迭代获取枚举实例
public enum EnumDemo1 {
    SPRING,SUMMER,WINTER;
    public static void main(String[] args) {
        for (EnumDemo1 obj : EnumDemo1.values()) {
            System.out.println(obj);
        }
    }
}

Enum API详解

  • int compareTo(E o):比较枚举实例的顺序,定义在对象o前面返回的是负值,在对象o之后返回正值。说人话(enum1.compareTo(enum2) 返回值为 ==enum1的索引值 - enum2的索引值 + 1==)

    System.out.println(SPRING.compareTo(SUMMER)); // -1
    
  • String name():返回枚举值的名称

  • String toString():返回枚举值的名称,同name方法的作用是一样的,源码二者均是返回的name

  • int ordinal():返回枚举值的索引值,第一个默认是0

  • readObject(ObjectInputStream in)和readObjectNoData(),保证常量实例唯一, 重写覆盖默认序列化规则

参考:https://stackoverflow.com/questions/34589325/why-default-serialization-is-prevented-in-enum-class

  • public static<T extends Enum<T>> T valueOf(Class<T> enumType,String name):返回指定枚举类中指定名称的枚举值
System.out.println(Enum.valueOf(EnumDemo1.class,"SPRING"));

抽象枚举类

抽象枚举类不需要使用abstract显示声明,里面定义一个抽象方法就表示该枚举类是一个抽象枚举类,与普通抽象类相似

public enum  EnumDemo3{

    OK{
        @Override
        public void info() {
            // todo
        }
    };

    public abstract void info();
}

编译后发现,系统会自动给它添加abstract,同时生成一个OK的匿名class

Compiled from "EnumDemo3.java"
public abstract class enumdemo.EnumDemo3 extends java.lang.Enum<enumdemo.EnumDemo3> {
  public static final enumdemo.EnumDemo3 OK;

  public static enumdemo.EnumDemo3[] values();
    Code:
       0: getstatic     #2                  // Field $VALUES:[Lenumdemo/EnumDemo3;
       3: invokevirtual #3                  // Method "[Lenumdemo/EnumDemo3;".clone:()Ljava/lang/Object;
       6: checkcast     #4                  // class "[Lenumdemo/EnumDemo3;"
       9: areturn

实际使用

原先的项目组里面是使用一个Constant类定义整个项目里面常用的常量和返回码、错误码、业务码,挺乱的而且容易忘记还需要经常维护查看对应的业务信息。

后面升级就使用了枚举类进行改造,定义一个接口控制总的行为,根据具体的功能和业务去实现对应的常量信息。

后面项目组解散换了一个古老的项目,它把编码放在一个常量类里面,然后定义的变量和对应的业务文字描述用一个键值对的方式放在一个code.properties文件里面(坑爹)。重点是这个文件的格式是ANSI,使用eclipse会自动把汉字解析出来,但是我用的是idea尼玛全是一堆16进制字符,整的我没脾气了,问了项目组的人咋个设计成这个样子(遗留问题,不晓得,吐血)。

idea中自动将ANSI中的数据解析设置:settings ----> Editor ----> File Encodings ----> 勾选 Transparent native-to-ascii conversion。

这样弄我没感觉到有什么优势,每次使用都要根据key去文件里面拿一边特别不方便,查对应的业务编码信息的时候还需要去找到这个文件然后在find一下,感觉有种脑子被门夹的感觉。

改造

public interface EnumPower {
    public String getCode();
    public String getMessage();
}

public enum ReturnCode implements EnumPower{
   SUCCESS("0","成功"),
   FAIL("1","失败");
   private final String code = null;
   private final String message = null;
   private static Hashtable<String, ReturnCode> aliasEnums;

   ReturnCode(String code, String message) {
       this.code = code;
       this.message = message;
       this.init(code, message);
   }

   private void init(String code, String message) {
       synchronized (this.getClass()) {
           if (aliasEnums == null) {
               aliasEnums = new Hashtable<String, ReturnCode>();
           }
       }
       aliasEnums.put(code, this);
       aliasEnums.put(message, this);
   }

   public static ReturnCode valueOfAlias(String alias) {
       return aliasEnums.get(alias);
   }

   public static ReturnCode valueOfAlias(char alias) {
       return aliasEnums.get(String.valueOf(alias));
   }

   @Override
   public String getCode() {
       return this.code;
   }

   @Override
   public String getMessage() {
       return this.message;
   }

   @Override
   public String toString() {
       return this.getMessage() + "〔信息代码:" + this.getCode() + "〕";
   }
}

总结:

​ 系统会为枚举类自动创建里面定义好的实例,因此它的构造方法必须是private。

​ 枚举类也是类,所以构造方法里面也可以带参数,它的特性就决定了它能够自带业务信息在里面

​ 不好的一点是不能通过定义的实例反向定位被调用的地方,只能通过搜索SUCCESS来确定,所以一般定义之后不要去改,否则你又不确定改完之后所有调用的地方都符合你要的业务就会有问题。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352

推荐阅读更多精彩内容