enum枚举类型
Thinkinjava这本书,不得不说的确是经典,但是今天看到了枚举,实在忍不住吐槽了,感觉书上的内容完全没有讲出enum的用法,百度后写此博客。
enum定义的枚举类就是class,其定义方法不是通过继承,我们用关键字enum来声明枚举类型,不可以通过显式继承该抽象类的方式来声明,并且该类是一个不可以被继承的final类。其枚举值都是该枚举类的类静态常量,注意:这些枚举值都是publicstaticfinal的,所以可以通过可以通过Enum类型名直接引用该常量,如类名.常量名,因此枚举类中的枚举值最好全部大写。
一个枚举类的枚举对象里面的值都必须是唯一的,可以把相同类型的常量分组到一个枚举类型里。枚举的一个突出优点在于它能够保证单例,它的这个优点让它和switch成了绝配,在jdk1.5之前,switch只能支持int和char类型,局限了switch的使用范围。当switch可以和enum搭配使用的时候,这个限制被突破了,理论上我们可以借助enum对任意具有相同类型的对象使用switch。
Thinkinjava上这一节的练习是创建一个包含纸币最小类型的enum并为其写一个switch语句,对于每一个case输出该特定货币的描述,这个问题很好的解释了enum的作用,最小货币就是0.1,0.2,0.5,1,2,5这些double数据,如果没有enum的配合,switch是不能接受double型作为变量的,下面在代码中讲解enum的用法。
首先是enum的定义类
/* 枚举也可以象一般的类一样添加方法和属性, * 你可以为它添加静态和非静态的属性或方法, * 这一切都象你在一般的类中做的那样. * 枚举类是通过enum关键字声明来定义的 */public enum Enum_Money { // 枚举列表必须写在最前面,否则编译出错,枚举列表只支持String类型,但是允许在枚举值后用括号添加构造。如果只是最普通的枚举没有其他方法枚举结尾可以不加分号,否则必须加Not(0.1),MILD(0.2),MEDIUM(0.5),HOT(1),FLAMING(2);private double money;/*通过括号赋值,而且必须有带参构造器和一属性跟方法,否则编译出错* 赋值必须是都赋值或都不赋值,不能一部分赋值一部分不赋值* 如果不赋值则不能写构造器,赋值编译也出错*///构造器默认也只能是private, 从而保证构造函数只能在内部使用Enum_Money(double money){this.money=money;}public double getReturn(){return money;}} 然后是调用类
public class Test_Enum {public static void main(String[] ARGS){/*通过values()获得枚举值的数组,按照enum常量声明的顺序*/for(Enum_Money money:Enum_Money.values())/*ordinal()返回枚举值在枚举中的索引位置,从0开始,顺序为enum声明的顺序*/System.out.println(money.getReturn()+" "+money.ordinal());/** 枚举类型是一种类型,用于定义变量,,以限制变量的赋值 赋值时通过"枚举名.值"来取得相关枚举中的值*/Enum_Money money = Enum_Money.MEDIUM;switch (money) {case Not:System.out.println("1毛");break;case MEDIUM: System.out.println("2毛");break;default:break;} }}
下面是enum类的源码分析
1.publicabstractclassEnum<EextendsEnum<E>>
2.implementsComparable<E>,Serializable{
3.
4.privatefinalStringname;
5.
6.//当前枚举常量名称
7.publicfinalStringname(){
8.returnname;
9.}
10.
11.privatefinalintordinal;
12.
13.//当前枚举常量次序,从0开始
14.publicfinalintordinal(){
15.returnordinal;
16.}
17.
18.//专有构造器,我们无法调用。该构造方法用于由响应枚举类型声明的编译器发出的代码。
19.protectedEnum(Stringname,intordinal){
20.this.name=name;
21.this.ordinal=ordinal;
22.}
23.
24.//返回枚举常量的名称,默认是返回name值。可以重写该方法,输出更加友好的描述。
25.publicStringtoString(){
26.returnname;
27.}
28.
29.//比较当前枚举常量是否和指定的对象相等。因为枚举常量是单例的,所以直接调用==操作符。子类不可以重写该方法。
30.publicfinalbooleanequals(Objectother){
31.returnthis==other;
32.}
33.
34.//返回该枚举常量的哈希码。和equals一致,该方法不可以被重写。
35.publicfinalinthashCode(){
36.returnsuper.hashCode();
37.}
38.
39.//因为枚举常量是单例的,所以不允许克隆。
40.protectedfinalObjectclone()throwsCloneNotSupportedException{
41.thrownewCloneNotSupportedException();
42.}
43.
世上没有绝望的处境,只有对处境绝望的人。