【原理】
写一个枚举,相信大家都会,如:
monospace; display: block; letter-spacing: 0px;">1public?enum?City?{Guangzhou,?Shenzhen,?Dongguan}
这是个城市的枚举类,包含广州、深圳、东莞三个城市枚举值,但是它怎么用呢?它的背后的真面目是怎样的呢?
下面我们来反编译一下这个枚举,结果得出:
1public?final?class?City??extends?Enum<City>??{
2????public?static?final?City[]?values()?{
3????????return?(City[])?$VALUES.clone();
4????}
5????public?static?City?valueOf(String?name)?{
6????????return?(City)?Enum.valueOf(City,?name);
7????}
8????//?构造函数
9????private?City(String?s,?int?i)?{
10????????super();
11????}
12????public?static?final?City?Guangzhou;
13????public?static?final?City?Shenzhen;
14????public?static?final?City?Dongguan;
15
16????private?static?final?City?$VALUES[];
17????//?实例化枚举
18????static?{
19????????Guangzhou?=?new?City("Guangzhou",?0);
20????????Shenzhen?=?new?City("Shenzhen",?1);
21????????Dongguan?=?new?City("Dongguan",?2);
22????????$VALUES?=?(new?City[]?{?Guangzhou,?Shenzhen,?Dongguan?});
23????}
24}
从这个类中我们可以看出几点:
1)是个类 并且是final类,继承与java.lang.Enum类?不可继承。
2)用static块初始化。
3)定义了几个final类型的City对象,并且在static块中初始化。
由此可以知道,enum本质是一个final类,而JavaAPI的设计出的这个Enum,是一个被封装之后的类,旨在提供一种代码简洁而高效的类型管理组件,简化开发者编码。这当然是废话啦,各位看看,同样是功能的两种写法哪一种更简洁?哪一种更值得用?
我们再来看看enum接口类的源码:
1public?abstract?class?Enum<E?extends?Enum<E>>
2????????implements?Comparable<E>,?Serializable?{
3????//枚举常量名称
4????private?final?String?name;
5??//返回枚举常量名称
6????public?final?String?name()?{
7????????return?name;
8????}
9????//枚举常量的序数?初始值为0?根据位置而得出
10????private?final?int?ordinal;
11//????返回枚举常量的序数
12????public?final?int?ordinal()?{
13????????return?ordinal;
14????}
15????//私有构造函数,程序无法直接调用改函数进行初始化
16????//它用于由响应枚举类型声明的编译器发出的代码
17????//@param?name:枚举常量的名称
18????//@param?ordinal:?枚举常量的序数
19????protected?Enum(String?name,?int?ordinal)?{
20????????this.name?=?name;
21????????this.ordinal?=?ordinal;
22????}
23????//和name()是一个意思
24????public?String?toString()?{
25????????return?name;
26????}
27????//判断是否相同对象的函数
28????public?final?boolean?equals(Object?other)?{
29????????return?this==other;
30????}
31????//为枚举返回一个hashCode
32????public?final?int?hashCode()?{
33????????return?super.hashCode();
34????}
35????//克隆函数
36????protected?final?Object?clone()?throws?CloneNotSupportedException?{
37????????throw?new?CloneNotSupportedException();
38????}
39????//比较此枚举与指定对象的顺序(编号)。
40????//在该对象小于、等于或大于指定对象时,分别返回负整数、零或正整数。
41????//枚举常量只能与相同枚举类型的其他枚举常量进行比较。
42????//该方法实现的自然顺序就是声明常量的顺序。?
43????public?final?int?compareTo(E?o)?{
44????????Enum<?>?other?=?(Enum<?>)o;
45????????Enum<E>?self?=?this;
46????????if?(self.getClass()?!=?other.getClass()?&&?//?optimization
47????????????self.getDeclaringClass()?!=?other.getDeclaringClass())
48????????????throw?new?ClassCastException();
49????????return?self.ordinal?-?other.ordinal;
50????}
51//?以下方法略过....
52}
有了这个抽象类Enum的源码,我们基本上知道枚举是怎么使用的了,下面是一些常用的方法:
方法名
返回值
说明
name()
String
返回枚举的名称
ordinal()
int
返回枚举常量的序数
compareTo(E o)
int
比较此枚举与指定对象的顺序(编号)。
在该对象小于、等于或大于指定对象时,分别返回负整数、零或正整数。
枚举常量只能与相同枚举类型的其他枚举常量进行比较。
该方法实现的自然顺序就是声明常量的顺序
? ? ?
【使用方式】
Enum类实现三种枚举:
1)最常用:
1public?enum?Num?{
2????ONE,TWO,THREE;
3}
?
2)定义带参构造函数:
1public?enum?EnumTest{
2????ONE("1","YI");
3????private?String?name;
4????private?String??value;
5????//一个参
6????private?EnumTest(String?name){
7????????this.name=name;
8????}
9????//两个参数
10????private?EnumTest(String?name,String?value){
11????????this.name=name;
12????????this.value=value;
13????}
14????//...多个参数
15????public?static?void?main(String[]?args)?{
16????????System.out.println(EnumTest.ONE.name);
17????????System.out.println(EnumTest.ONE.value);
18????}
19}
?
3)抽象方法实现:
?
1public?enum?EnumTest{
2????ONE("1")?{
3????????@Override
4????????public?void?handle()?{
5????????????//?TODO?Auto-generated?method?stub
6????????}
7????};
8????private?String?name;
9????private?EnumTest(String?name){
10????????this.name=name;
11????}
12????//定义抽象方法
13????public?abstract?void?handle();
14????public?static?void?main(String[]?args)?{
15????????//调用
16????????EnumTest.ONE.handle();
17????}
18}
?
【注意事项】
1)不能继承,因为枚举类本身已经继承了Enum抽象类,而Java是单继承?
2)枚举的第一行必须是枚举项,所有其它的变量和方法都必须在枚举项后面?
3) 枚举类可以定义抽象方法,但没枚举项必须重写所有抽象方法?
4)可以在switch中使用枚举,它的使用方法如下:
1switch(EnumTest.ONE){
2
3case?ONE:
4
5break;
6
7case?TWO:
8
9break;
10
11}
?
?
?
觉得本文对你有帮助?请分享给更多人
关注「编程无界」,提升装逼技能
?
?
??
?