java SE 1.5以后的版本中,引入了一个新的引用类型----枚举类型。枚举类型指的是由一组固定的常量组合成的合法值类型,例如一年的四季,一个星期的7天,红绿蓝三色、状态的可用与不可用等,都是枚举类型的示例。

java中定义枚举的方法如下:


Code:



  1. public enum


java中定义枚举的基本要求有:

1.使用关键字enum。

2.类型名称,比如这里的Year。

3.一串允许的值,比如上面定义的春夏秋冬四季。

4。枚举可以单独定义在一个文件中,也可以嵌在其他Java类中。

除了这样的定义以外,用户还有一些其他选择:

1。枚举可以实现一个或多个接口(interface)。

2。可以定义新的变量和方法。

3。可以定义根据具体枚举值而相异的类。

java枚举类的原理也比较简单,就是在编译器编译的时候,枚举类型会被转换成为static final类型的一个类。比如以上定义枚举类被编译后的代码如下所示:


Code:



1. //源代码 
2. public class
3. {   
4. public enum
5. public static void
6. }


Code:



1. //编译后生成的class文件经过反编译以后的代码 
2. public class
3. {   
4. public static final class Year extends
5.     {   
6.   
7. public static
8.         {   
9. return
10.         }   
11.   
12. public static
13.         {   
14. return
15.         }   
16.   
17. public static final
18. public static final
19. public static final
20. public static final
21. private static final
22.   
23. static
24.         {   
25. new Year("SPRING", 0);   
26. new Year("SUMMER", 1);   
27. new Year("FALL", 2);   
28. new Year("WINTER", 3);   
29. new
30.                 SPRING, SUMMER, FALL, WINTER   
31.             });   
32.         }   
33.   
34. private Year(String s, int
35.         {   
36. super(s, i);   
37.         }   
38.     }   
39.   
40.   
41. public
42.     {   
43.     }   
44.   
45. public static void
46.     {   
47.     }   
48. }


 那么通过看编译后生成的代码可以看出,大概有这么几个规律:

1.定义的枚举变量变成了一个类名,并且继承了java.lang.Enum类。

2.枚举常量被变成了static final Year类型的。并且多了一个枚举类类型的数组变量private static final

3.枚举类中多了这么几个方法。


Code:



1. public static Year[] values(){...}   //返回该枚举对象定义的一个枚举类型数组。  
2. public static Year valueOf(String s){...}//根据传入的字符串返回相应的枚举值。    
3. private Year(String s, int i){...}   //构造方法


 4.多了一个静态执行块。


Code:



1. static
2.         {       
3. new Year("SPRING", 0);//调用构造方法类给枚举常量给值。 
4. new Year("SUMMER", 1);       
5. new Year("FALL", 2);       
6. new Year("WINTER", 3);       
7. new Year[] {  //初始化枚举类类型数组   
8.                 SPRING, SUMMER, FALL, WINTER       
9.             });       
10.         }


所以枚举类型的值是直接用“枚举名.枚举值”来访问的,使用如下所示。


Code:


1. public class
2. {   
3. enum
4. public static void
5.         Year thisYear = Year.SPRING;   
6.         Year[] ty = Year.values();   
7. for(Year tyear : ty){   
8.             System.out.println(tyear);   
9.         }   
10. "SPRING");   
11. switch(yearSeason){   
12. case
13. "春天");break;   
14. case
15. "夏天");break;   
16. case
17. "秋天");break;   
18. case
19. "冬天");break;   
20. default:   
21. "四季平安");break;   
22.         }   
23.     }   
24. }


运行结果:

SPRING
SUMMER
FALL
WINTER
春天

由于枚举类型就是java.lang.Enum类的子类,因此,在枚举类型中可以添加属性,构造器和方法,并可以实现任意的接口,而且提供了所有Object类的方法,使用示例如下:


Code:



1. //sun公司提供的enum使用示例 
2. public class
3. public enum
4. 3.303e+23, 2.4397e6),   
5. 4.869e+24, 6.0518e6),   
6. 5.976e+24, 6.37814e6),   
7. 6.421e+23, 3.3972e6),   
8. 1.9e+27,   7.1492e7),   
9. 5.688e+26, 6.0268e7),   
10. 8.686e+25, 2.5559e7),   
11. 1.024e+26, 2.4746e7),   
12. 1.27e+22, 1.137e6);   
13.   
14.   
15. private final double mass;   // in kilograms 
16. private final double radius; // in meters 
17.   
18. double mass, double
19.         {   
20. this.mass = mass;   
21. this.radius = radius;   
22.         }   
23.   
24. private double mass()   { return
25. private double radius() { return
26. // universal gravitational constant  (m3 kg-1 s-2) 
27. public static final double G = 6.67300E-11;   
28.   
29. double
30. return
31.         }   
32. double surfaceWeight(double
33. return
34.         }      
35.     }    
36. public static void
37. for(int i = 0;i<Planet.values().length;i++){   
38.                 System.out.println(Planet.values()[i]);   
39. //System.out.println(Planet.MERCURY); 
40. //System.out.println(Planet.values()[i].mass()); 
41. //System.out.println(Planet.values()[i].surfaceGravity()); 
42. //System.out.println(Planet.values()[i].surfaceWeight(1.27e+22)); 
43.             }   
44.         }   
45. }


以上使用方法大体规律为:

构造方法,和枚举值中的参数,参数的出处(如上例的mass和radius)必须要联系起来。其他变量和方法没什么特殊要求。看下面代码所示:


Code:


1. MERCURY (3.303e+23, 2.4397e6),   
2. 以及   
3. private final double mass;   // in kilograms 
4. private final double radius; // in meters 
5. 以及   
6. Planet(double mass, double
7. this.mass = mass;   
8. this.radius = radius;   
9. }

为什么上面要说他们必须要有联系呢。先别多说,看看反编译后的代码。如下所示:


Code:



1. import
2.   
3. public class
4. {   
5. public static final class Planet extends
6.     {   
7.   
8. public static
9.         {   
10. return
11.         }   
12.   
13. public static
14.         {   
15. return
16.         }   
17.   
18. private double
19.         {   
20. return
21.         }   
22.   
23. private double
24.         {   
25. return
26.         }   
27.   
28. double
29.         {   
30. return (6.6729999999999999E-011D * mass) / (radius * radius);   
31.         }   
32.   
33. double surfaceWeight(double
34.         {   
35. return
36.         }   
37.   
38. public static final
39. public static final
40. public static final
41. public static final
42. public static final
43. public static final
44. public static final
45. public static final
46. public static final
47. private final double
48. private final double
49. public static final double G = 6.6729999999999999E-011D;   
50. private static final
51.   
52. static
53.         {   
54. new Planet("MERCURY", 0, 3.3030000000000001E+023D, 2439700D);   
55. new Planet("VENUS", 1, 4.8690000000000001E+024D, 6051800D);   
56. new Planet("EARTH", 2, 5.9760000000000004E+024D, 6378140D);   
57. new Planet("MARS", 3, 6.4209999999999999E+023D, 3397200D);   
58. new Planet("JUPITER", 4, 1.9000000000000001E+027D, 71492000D);   
59. new Planet("SATURN", 5, 5.6879999999999998E+026D, 60268000D);   
60. new Planet("URANUS", 6, 8.686E+025D, 25559000D);   
61. new Planet("NEPTUNE", 7, 1.0239999999999999E+026D, 24746000D);   
62. new Planet("PLUTO", 8, 1.2700000000000001E+022D, 1137000D);   
63. new
64.                 MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE, PLUTO   
65.             });   
66.         }   
67.   
68. private Planet(String s, int i, double d, double
69.         {   
70. super(s, i);   
71.             mass = d;   
72.             radius = d1;   
73.         }   
74.     }   
75.   
76.   
77. public
78.     {   
79.     }   
80.   
81. public static void
82.     {   
83. for(int i = 0; i < Planet.values().length; i++)   
84.             System.out.println(Planet.values()[i]);   
85.   
86.     }   
87. }


通过观察不难发现有以下几个特点:

1.构造方法多了两个参数,且为private的。private Planet(String s, int i, double d, double

2.静态执行快中,调用了构造方法,构造方法的参数为4个,后面多出的两个参数也正是枚举常量后的参数MERCURY (3.303e+23, 2.4397e6)...。

所以,编译器在编译的过程中是根据构造方法来增加编译后构造方法中多余的参数。

下面一个实例是利用枚举来实现加减乘除运算。


Code:



1. public class
2. public enum
3. double eval(double x,double y){return
4. double eval(double x,double y){return
5. double eval(double x,double y){return
6. double eval(double x,double y){return
7.   
8. abstract double eval(double x,double
9.     }   
10. public static void
11.     {   
12. for(int i = 0;i<Operation.values().length;i++){   
13. 3,4));   
14.         }   
15.     }   
16. }


运行结果:

7.0
-1.0
12.0
0.75

第一次些学习笔记,不知道写的对不对,反正先写出来,有错误希望各位老师和同学指出我好改正。

差点忘说了。网上的资料很多,其中有一篇是最全的,如下:


 jdk 1.5 枚举替代类: