枚举枚举类型概述1什么是枚举类型word文档的对齐方式有几种:左对齐、居中对齐、右对齐;开车的方向有几种:前、后、左、右;枚举就是有限实现个数的类型,你可能会说,byte类型也只有256个,没错,但我们真实定义为枚举的类型,一般最多也就十多个实例,再多就不会定义为枚举了。2JDK1.4之前的枚举类型在JDK1.4之前没有枚举类型,都是使用int或字符串类型来表示枚举,如果枚举只有两个选项,那么连int都用不上,只需要使用boolean类型即可。例如:BorderLayout类的方位给出五个:CENTER、EAST、SOUTH、WEST、NORTH。当使用容器类的方法添加组件时:add(newButton(),“CENTER”),这是合法的,但因为String类型太过宽泛,所以可能会出现add(newButton(),“哈哈”)的调用可能,这会导致运行时出现异常。所以,JDK1.5又新增了枚举类型。3定义枚举类型定义枚举类型需要使用enum关键字,例如:publicenumDirection{FRONT、BEHIND、LEFT、RIGHT;}Directiond=Direction.FRONT;注意,每个枚举选项之间是用逗号隔开的。如果枚举类没有构造器、方法等,在最后一个枚举选择后面可以不打分号。但是如果枚举类还有其他成员,那么就要在最后一个枚举项后面添加分号了。Direction类型只有四个选项,你可以理解为这个枚举类只有四个实例对象一样。外界无法去创建新的枚举对象,只能从这四个中去选择。其实大多数时候,我们使用枚举类型还是与以及使用int或String表示的枚举一样,基本上都是很简单的。4枚举与switch1.5开始枚举类型可以在switch中使用!在1.7之后,String类型也可以放到switch中使用了。Directiond=Direction.FRONT;switch(d){caseFRONT:System.out.println(前面);break;caseBEHIND:System.out.println(后面);break;caseLEFT:System.out.println(左面);break;caseRIGHT:System.out.println(右面);break;default:System.out.println(错误的方向);}Directiond1=d;System.out.println(d1);注意,在switch中,不能使用枚举类名称,例如:“caseDirection.FRONT:”这是错误的,因为编译器会根据switch中d的类型来判定每个枚举类型,在case中必须直接给出与d相同类型的枚举选项,而不能再有类型。枚举类也是类1所有枚举类都是Enum的子类所有枚举类都默认是Enum类的子类,无需我们使用extends来继承。这说明Enum中的方法所有枚举类都可以的。intcompareTo(Ee):比较两个枚举常量谁大谁小,其实比较的就是枚举常量在枚举类中声明的顺序,例如FRONT的下标为0,BEHIND下标为1,那么FRONT小于BEHIND;booleanequals(Objecto):比较两个枚举常量是否相等;inthashCode():返回枚举常量的hashCode;Stringname():返回枚举常量的名字;intordinal():返回枚举常量在枚举类中声明的序号,第一个枚举常量序号为0;StringtoString():把枚举常量转换成字符串;staticTvalueOf(ClassenumType,Stringname):把字符串转换成枚举常量。2枚举类的构造器枚举类也可以有构造器,构造器不能给出访问修饰,而且默认都是private构造器。因为枚举类的实例不能让外界来创建!enumDirection{FRONT,BEHIND,LEFT,RIGHT;Direction(){System.out.println(hello);}}3枚举类的方法再次强调,枚举类也是类,也可以有构造器、方法和属性,只是对构造器有一些限制而已。在语法上有一些怪异罢了!enumDirection{FRONT,BEHIND,LEFT,RIGHT;publicvoidfun(){System.out.println(helloEnum!);}}Direction.FRONT.fun();4枚举类的属性枚举类也可以有属性。但是,如果每个枚举常量的属性值如果都相同,那就失去了意义,我们需要让每个枚举常量的属性值不同,那么就需要自己使用构造器来创建枚举常量,然后在构造器中给每个枚举常量传递不同的值。enumDirection{FRONT(前面),BEHIND(后面),LEFT(左面),RIGHT(右面);privateStringexplain;Direction(Stringexplain){this.explain=explain;}publicvoidsetExplain(Stringexplain){this.explain=explain;}publicStringgetExplain(){returnexplain;}}Stringexplain=Direction.FRONT.getExplain();System.out.println(explain);5使用匿名类来创建枚举常量还可以使用匿名类来创建枚举常量,这说明枚举常量的类型是当前枚举类的子类,而且是个匿名类。这可以让每个枚举常量有自己的类型,当然有自己的类型不是目的,而是有自己的行为才是目的!但是我们知道就算给匿名类添加了自己独有的方法,也是无法调用的,因为匿名类没有名字,只能使用父类的引用指向匿名类的实例,而多态之后只能调用父类中存在的方法。所以,使用这种情况时,通常是为了让每个枚举常量重写当前枚举类中的方法(抽象方法)。enumDirection{FRONT(){publicvoidfun(){System.out.println(FROND:重写了fun()方法);}},BEHIND(){publicvoidfun(){System.out.println(BEHIND:重写了fun()方法);}},LEFT(){publicvoidfun(){System.out.println(LEFT:重写了fun()方法);}},RIGHT(){publicvoidfun(){System.out.println(RIGHT:重写了fun()方法);}};publicvoidfun(){System.out.println(没有意义的方法);}}Direction.FRONT.fun();Direction.BEHIND.fun();Direction.LEFT.fun();Direction.RIGHT.fun();通常fun()方法应该定义为抽象的方法,因为每个枚举常量都会去重写它。你无法把Direction声明为抽象类,但需要声明fun()方法为抽象方法。enumDirection{FRONT(){publicvoidfun(){System.out.println(FROND:重写了fun()方法);}},BEHIND(){publicvoidfun(){System.out.println(BEHIND:重写了fun()方法);}},LEFT(){publicvoidfun(){System.out.println(LEFT:重写了fun()方法);}},RIGHT(){publicvoidfun(){System.out.println(RIGHT:重写了fun()方法);}};publicabstractvoidfun();}枚举类的特殊方法1每个枚举类都有两个特殊方法每个枚举类都有两个不用声明就可以调用的static方法,而且这两个方法不是父类中的方法。这又是枚举类特殊的地方,下面是Direction类的特殊方法。staticDirection[]values():返回本类所有枚举常量;staticDirectionvalueOf(Stringname):通过枚举常量的名字返回Direction常量,注意,这个方法与Enum类中的valueOf()方法的参数个数不同。枚举的真实世界1枚举也是编译期状态其实枚举也是编译期状态,在运行时JVM并不知道什么是枚举类型。这也就是说,编译器需要把枚举类型转换成普通类。enumDirection{FRONT,BEHIND,LEFT,RIGHT}finalclassDirectionextendsEnum{publicstaticfinalDirectionFRONT;publicstaticfinalDirectionBEHIND;publicstaticfinalDirectionLEFT;publicstaticfinalDirectionRIGHT;privatestaticfinalDirectionENUM$VALUES[];static{FRONT=newDirection(FRONT,0);BEHIND=newDirection(BEHIND,1);LEFT=newDirection(LEFT,2);RIGHT=newDirection(RIGHT,3);ENUM$VALUES=newDirection[]{FRONT,BEHIND,LEFT,RIGHT};}privateDirection(Strings,inti){super(s,i);}publicstaticDirection[]values(){Directionadirection[];inti;Directionadirection1[];System.arraycopy(adirection=ENUM$VALUES,0,adirection1=newDirection[i=adirection.length],0,i);returnadirection1;}publicstaticDirectionvalueOf(Strings){return(Direction)Enum.valueOf(Direction.class,s);}}