引言:枚举类;补充了一些额外知识点
 
枚举类 为什么要使用枚举类? 
安全性 (使用枚举类不会被反射获取,不可以与其他类型的值进行比较,防止错误)易读性 (枚举类比原本使用数字可以携带更多的信息,尤其是在日志记录时,更加容易) 
Enum类的核心API 所有枚举类,默认继承自java.lang.Enum类 ,该类有以下几个方法
1 2 3 String name ()   String toString ()   int  ordinal () 
注意:
尽量使用name()方法来返回字符串等效串,而不去使用toString 
 
为什么要使用name()?
 
因为你不能保证toString没有被重写!
导致此枚举类在序列化时有可能使字符串失去等效性 ,而使用name()就没有这种情况
一个枚举的Demo 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public  enum  Color  {    RED("红色" , 1 ),     GREEN("绿色" , 2 ),     BLANK("白色" , 3 ),     YELLO("黄色" , 4 );           private  String name;     private  int  index;          private  Color (String name, int  index)  {         this .name = name;         this .index = index;     }          @Override      public  String toString ()  {         return  "Color{"  +                 "name='"  + name + '\''  +                 ", index="  + index +                 '}' ;     } } 
测试一下API会返回什么?
1 2 3 4 Color  color  =  Color.BLANK;System.out.println(color.name());  System.out.println(color.toString());  System.out.println(color.ordinal());  
枚举类的特点 
枚举类继承自java.lang.Enum(因此枚举类不能继承其他类,但是可以实现接口) 
无法使用new创建实例(因为构造方法是私有的) 
定义的每个实例都是引用类型的唯一实例(唯一一个安全的构造单例模式的方法) 
可以在switch语句中使用 
 
枚举类的本质 我们自己建立的枚举类
1 2 3 public  enum  Weekday  {    SUN, MON, TUE, WED, THU, FRI, SAT; } 
在被编译器编译后是这样
1 2 3 4 5 6 7 8 9 10 11 12 13 public  final  class  Weekday  extends  Enum  {          public  static  final  Weekday  SUN  =  new  Weekday ();     public  static  final  Weekday  MON  =  new  Weekday ();     public  static  final  Weekday  TUE  =  new  Weekday ();     public  static  final  Weekday  WED  =  new  Weekday ();     public  static  final  Weekday  THU  =  new  Weekday ();     public  static  final  Weekday  FRI  =  new  Weekday ();     public  static  final  Weekday  SAT  =  new  Weekday ();               private  Color ()  {} } 
由于ordinal()方法依赖于排序树,所以改变枚举类常量的顺序就会发生变化,不利于程序的鲁棒性
建议枚举类代码写为
1 2 3 4 5 6 7 8 public  enum  Weekday  {    SUN(0 ), MON(1 ), TUE(2 ), WED(3 ), THU(4 ), FRI(5 ), SAT(6 );     public  final  int  dayValue;          Weekday(int  dayValue) {         this .dayValue = dayValue;     } } 
判断枚举常量的名字,要始终使用name()方法,绝不能调用toString()! 
在switch语句中使用 switch()语句支持的类型有:byte char short int及其包装类 、以及枚举类 和String
有关switch这方面推荐博客CSDN博主 由零开始Leon 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Weekday  day  =  Weekday.SUN;switch (day) {case  MON:case  TUE:case  WED:case  THU:case  FRI:    System.out.println("Today is "  + day + ". Work at office!" );     break ; case  SAT:case  SUN:    System.out.println("Today is "  + day + ". Work at home!" );     break ; default :    throw  new  RuntimeException ("cannot process "  + day); 
枚举的values()方法 枚举类都有一个values方法,但注意,这个方法并不来自父类Enum,而是编译器增加的一个方法
The compiler automatically adds some special methods when it creates an enum. For example, they have a static values method that returns an array containing all of the values of the enum in the order they are declared. (Oracle官方文档 )
翻译:编译器在创建enum时,会自动添加一些方法。比如values静态方法,会返回一个该枚举类型的数组
 
工作中经常会遇到一个枚举类,需要通过Int获取他的String(或是相反)的情况,这里给出一个模板 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 public  enum  EnumTemplate  {    CREATE(0 ,"create" ),     TOUCH(1 ,"touch" ),     SUBMIT(2 , "submit" );          private  String tag;     private  Integer id;     EnumTemplate(Integer id, String tag) {         this .tag = tag;         this .id = id;     }          public  static  String getNameById (Integer id) {         for  (EnumTemplate value : values()) {             if (value.id.equals(id)){                 return  value.tag;             }         }         return  "" ;     }          public  static  Integer getIdByName (String name) {         return  Arrays.stream(values())                 .collect(Collectors.toList())                 .stream()                 .filter(x -> name.equals(x.tag))                 .map(EnumTemplate::getId)                 .findFirst().orElse(0 );     }     public  String getTag ()  {         return  tag;     }     public  Integer getId ()  {         return  id;     } } 
注意 :工作强烈建议使用普通方法 而不是流式写法,效率差太多了 (差距一百多倍)。
枚举的更多写法 接口的内部枚举 有时候我们会遇到这种情况,枚举有了分类,比如:腾讯有QQ与微信,QQ有QQ登录的和平精英、王者荣耀,微信同样也有,但是我们想用枚举标识这两种不同的账号,我们可以如此创建这个枚举类。
同一个接口Tencent下,实现了两个枚举类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 public  interface  Tencent  {    enum  WX {         WX_WZRY(0 , "王者荣耀" ),         WX_HPJY(1 , "和平精英" );         private  Integer id;         private  String name;         WX(Integer id, String name) {             this .id = id;             this .name = name;         }         public  Integer getId ()  {             return  id;         }         public  String getName ()  {             return  name;         }     }     enum  QQ {         QQ_WZRY(0 , "王者荣耀" ),         QQ_HPJY(1 , "和平精英" );         private  Integer id;         private  String name;         QQ(Integer id, String name) {             this .id = id;             this .name = name;         }         public  Integer getId ()  {             return  id;         }         public  String getName ()  {             return  name;         }     } } 
在调用时,我们需要通过接口名调用,才能拿到想要的数据:
1 TencentEnum.WX.WX_HPJY.getName(); 
接口实现抽象方法 枚举类可以有抽象方法,并且需要在实例中实现。
假设现在需要给和平精英的玩家发红包,但是发的个数不同,就可以这么写:
(但这种写法具体有什么好处,有待考究)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 public  enum  TencentEnum2  {    WX_HPJY(0 , "和平精英" ){         private  final  Integer  num  =  100 ;         @Override          public  int  sendHongBao ()  {             return  num;         }     },     QQ_HPJY(1 , "和平精英" ){         private  final  Integer  num  =  1 ;         @Override          public  int  sendHongBao ()  {             return  num;         }     },     WX_WZRY(2 , "王者荣耀" ){         @Override          public  int  sendHongBao ()  {             return  0 ;         }     };     private  Integer id;     private  String name;     abstract  public  int  sendHongBao () ;     TencentEnum2(Integer id, String name) {         this .id = id;         this .name = name;     } } 
参考材料: 廖雪峰官方网站 CSDN博主 由零开始Leon