分享
 
 
 

[J2SE 5.0专题][2.4]类型安全的枚举

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

在细述J2SE 5.0中引入的类型安全枚举的用法之前,我想先简单介绍一下这一话题的背景。

我们知道,在C中,我们可以定义枚举类型来使用别名代替一个集合中的不同元素,通常是用于描述那些可以归为一类,而又有限数量的类别或者概念,如一周的每一天、月份、颜色、扑克牌、太阳系的行星、五大洲、四大洋、季节、学科、运算符,等等。它们通常看上去是这个样子:

typedef enum {SPRING, SUMMER, AUTUMN, WINTER} season;

实质上,这些别名被处理成int常量,比如0代表SPRING,1代表SUMMER,以此类推。因为这些别名最终就是int,于是你可以对它们进行四则运算,这就造成了语意上的不明确。另外,我们可以想象在这个枚举之后,我们又定义了一个

typedef enum {GREEN, HOLMES, RUSSELL, LEE, SUMMER} name_of_teacher;

因为C中的enum没有提供名字空间的区分,所以上面的两个enum就存在着冲突。

Java一开始并没有考虑引入枚举的概念,也许是出于维护Java语言简洁的考虑,但是时过境迁,对于枚举的需求并没有因为Java本身没有提供而消失,于是出现了一些常见的Java中的枚举设计模式,如int enum和typesafe enum,还有不少开源的枚举API和不开源的内部实现。

我大致说一下int enum模式和typesafe enum模式。所谓int enum模式就是模仿C中对enum的实现,如:

public class Season {

public static final int SPRING = 0;

public static final int SUMMER = 1;

public static final int AUTUMN = 2;

public static final int WINTER = 3;

}

这种模式跟C中的枚举没有太多本质上的区别,C枚举有的问题它基本上也有。而typesafe enum模式则要显得健壮得多:

public class Season {

private final String name;

private Season(String name) {

this.name = name;

}

public String toString() {

return name;

}

public static final Season SPRING = new Season("spring");

public static final Season SUMMER = new Season("summer");

public static final Season AUTUMN = new Season("autumn");

public static final Season WINTER = new Season("winter");

}

后一种实现首先通过私有的构造方法阻止了对该类的继承和显式实例化,因而我们只可能取得定义好的四种Season类别,并且提供了方便的toString()方法获取有意义的说明,而且由于这是一个完全意义上的类,所以我们可以很方便的加入自己的方法和逻辑来自定义我们的枚举类。不过自定义的枚举类也显然存在着不足:比如有太多的功能需要我们自己去实现,而且随着代码行数的增加,出错的可能性也在增加,我们也很难保证我们自定义的这些逻辑可以满足所有可能的情况;还有就是自定义的枚举类不能用于switch语句。

最终,Java决定拥抱枚举,在J2SE 5.0中,我们看到了这一变化。用一个实际的例子来说(借用Java官网上的例子,懒得想了):

public enum Operation {

PLUS { double eval(double x, double y) { return x + y; } },

MINUS { double eval(double x, double y) { return x - y; } },

TIMES { double eval(double x, double y) { return x * y; } },

DIVIDE { double eval(double x, double y) { return x / y; } };

// Do arithmetic op represented by this constant

abstract double eval(double x, double y);

}

然后可以通过下面的代码来试验上面这个枚举类:

public static void main(String args[]) {

double x = Double.parseDouble(args[0]);

double y = Double.parseDouble(args[1]);

for (Operation op : Operation.values()) {

System.out.println(x + " " + op + " " + y + " = " + op.eval(x, y));

}

}

怎么样,使用枚举,我们能够很方便的实现一些原先比较麻烦和费事的功能了吧?有几点注意一下,那就是:

1- J2SE 5.0中的枚举中,所有项都自动默认为static(很显然这是必要的)

2- 对于每一个枚举类,都可以调用公用的方法,如values() - 返回一个包含了所有枚举项的数组

3- 对于每个枚举项,也能够调用基本的对象方法,如toString()

4- 从某种意义上讲,enum关键字其实就是代表了一种新的类型的class,因为从本质上看,它就是一个类

另外,在java.util包中新增了两个类用于更方便的处理枚举类型,这两个类分别是EnumSetEnumMap

有关类型安全的枚举更详细的信息,参考这里

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有