enum自jdk1.5引入,其實是一個特殊的class,寫法簡單,JVM自動幫你封裝了很多東西而已
package scjp;<br />public class Test {<br />public static void main(String args[]) {<br />System.out.println(CoffeeSize.BIG == CoffeeSize.BIG);<br />}<br />}<br />enum CoffeeSize {<br />// 8, 10 & 16 are passed to the constructor<br />BIG(8), HUGE(10), OVERWHELMING(16);<br />CoffeeSize(int ounces) { // constructor<br />this.ounces = ounces;<br />System.out.println(ounces);<br />}<br />private int ounces; // an instance variable<br />public int getOunces() {<br />return ounces;<br />}<br />}<br />
編譯後的enum(上面是CoffeeSize)也會對應產生一個CoffeeSize.class
通過類彙編反編譯 javap -c CoffeeSize 得到如下代碼
Compiled from "Test.java"<br />final class scjp.CoffeeSize extends java.lang.Enum{<br />public static final scjp.CoffeeSize BIG;<br />public static final scjp.CoffeeSize HUGE;<br />public static final scjp.CoffeeSize OVERWHELMING;<br />static {};<br /> Code:<br /> 0:new#1; //class scjp/CoffeeSize<br /> 3:dup<br /> 4:ldc#16; //String BIG<br /> 6:iconst_0<br /> 7:bipush8<br /> 9:invokespecial#17; //Method "<init>":(Ljava/lang/String;II)V<br /> 12:putstatic#21; //Field BIG:Lscjp/CoffeeSize;<br /> 15:new#1; //class scjp/CoffeeSize<br /> 18:dup<br /> 19:ldc#23; //String HUGE<br /> 21:iconst_1<br /> 22:bipush10<br /> 24:invokespecial#17; //Method "<init>":(Ljava/lang/String;II)V<br /> 27:putstatic#24; //Field HUGE:Lscjp/CoffeeSize;<br /> 30:new#1; //class scjp/CoffeeSize<br /> 33:dup<br /> 34:ldc#26; //String OVERWHELMING<br /> 36:iconst_2<br /> 37:bipush16<br /> 39:invokespecial#17; //Method "<init>":(Ljava/lang/String;II)V<br /> 42:putstatic#27; //Field OVERWHELMING:Lscjp/CoffeeSize;<br /> 45:iconst_3<br /> 46:anewarray#1; //class scjp/CoffeeSize<br /> 49:dup<br /> 50:iconst_0<br /> 51:getstatic#21; //Field BIG:Lscjp/CoffeeSize;<br /> 54:aastore<br /> 55:dup<br /> 56:iconst_1<br /> 57:getstatic#24; //Field HUGE:Lscjp/CoffeeSize;<br /> 60:aastore<br /> 61:dup<br /> 62:iconst_2<br /> 63:getstatic#27; //Field OVERWHELMING:Lscjp/CoffeeSize;<br /> 66:aastore<br /> 67:putstatic#29; //Field ENUM$VALUES:[Lscjp/CoffeeSize;<br /> 70:return<br />public int getOunces();<br /> Code:<br /> 0:aload_0<br /> 1:getfield#36; //Field ounces:I<br /> 4:ireturn<br />public static scjp.CoffeeSize[] values();<br /> Code:<br /> 0:getstatic#29; //Field ENUM$VALUES:[Lscjp/CoffeeSize;<br /> 3:dup<br /> 4:astore_0<br /> 5:iconst_0<br /> 6:aload_0<br /> 7:arraylength<br /> 8:dup<br /> 9:istore_1<br /> 10:anewarray#1; //class scjp/CoffeeSize<br /> 13:dup<br /> 14:astore_2<br /> 15:iconst_0<br /> 16:iload_1<br /> 17:invokestatic#55; //Method java/lang/System.arraycopy:(Ljava/lang/Object;ILjava/lang/Object;II)V<br /> 20:aload_2<br /> 21:areturn<br />public static scjp.CoffeeSize valueOf(java.lang.String);<br /> Code:<br /> 0:ldc#1; //class scjp/CoffeeSize<br /> 2:aload_0<br /> 3:invokestatic#61; //Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;<br /> 6:checkcast#1; //class scjp/CoffeeSize<br /> 9:areturn<br />}<br />
可以看到各個element其實是enum類的public static final 的instance,
還有包括:
public static scjp.CoffeeSize[] values();
public static scjp.CoffeeSize valueOf(java.lang.String);
等方法。
所以在一些ide(如eclipse)裡面 .後面會自動提示這些方法或屬性。
也可以用反射再次驗證一下類彙編代碼。
另外,enum的constructor只允許為private。
equals方法被聲明為final,所以不能override,以保證不同元素之間的比較返回false,相同元素返回true。
enum的override
public class Demo {</p><p>public static void main(String ...args) {// <--> String args[]<br />MyEnum.B.method();// output:<br />// B:method()</p><p>}<br />};</p><p>enum MyEnum{<br />A(1), B(2){//seems enum elements must be placed ahead of other fieds and methods<br />//override<br />public void method(){<br />System.out.println("B:method()");<br />}<br />};<br />private int value;<br />MyEnum(int value){<br />this.value = value;<br />}</p><p>// a common method<br />public void method(){<br />System.out.println("MyEnum:method()");<br />}<br />};
總結: enum可以看作一個特殊的class,文法上作了要求,比如constructor不能為public, 元素的聲明必須放在類的最前面。element為一些public static final的instance, enum不能在method裡聲明,等。