枚举类型是大多编程语言都有得内容,而在Java语言,在JDK1.5才进入枚举类型。在C语言中,枚举通常与Switch完成选择结构代码的编程。在没有加入枚举类型的Java JDK版本中,都是通过int常量与Switch完成选择代码,这种方法被专家称之为int枚举模式。文章将探讨int枚举模式的布不足,以及分析枚举类型在语言编程中的使用。
int枚举模式虽然可以完成相关的选择代码,且在定义int常量是,命名已可以让人非常容易理解。但是对于不同的应用环境,很容易错误的传入其他枚举组的int常量,这种情况也许在程序运行时不会出现错误,但是在程序的可维护上可能会大打折扣。比如:
/**
* for A's situation
*/
private final static int A_OPEN = 1;
private final static int A_WORKING = 2;
private final static int A_CLOSED = 3;
/**
* for B's situation
*/
private final static int B_OPEN = 1;
private final static int B_WORKING = 2;
private final static int B_CLOSED = 3;
以上代码,很容易在使用A的环境下传入B环境常量。这种情况,即使传错,程序在编译期也不会出现任何报错,因为二者都是int常量。
其次,int枚举模式是调试时,以及需要记录日志信息时,没有很好的方法将其翻译成字符串,打印出来的数字没有很好的信息提供。int枚举模式是编译时常量,程序编译时直接把值赋予到对应位置。
在Java新推出的JDK1.8版本,支持了String枚举模式,可以在Switch语句中与String枚举模式完成选择程序代码,这种很早在其他语言中支持的特性。String枚举类型虽然包含了丰富的输出信息,但是,String字符串很容易写错,编程习惯不好的情况下,把String常量硬编码到代码中,这种情况下,即使字符串书写出现错误,编译器无提示,运行时却出现错误。还有String枚举类型,运行时依赖字符串比较操作,性能上会有损耗。
Java枚举类型是真正的final类型,无可以访问的构造器,不能创建枚举类型的实例,也不能进行扩展。枚举类型还提供了编译期安全,不会出现在需要A情况的环境下传入B。而且枚举类型还可通过toString()方法输出相应字符串。
枚举类型除了完善Int枚举模式的不足之外,枚举类型还可以定义自己的域和方法,以及实现接口。域和方法可以使具体实现与枚举常量联系起来,
举例如下,换算人民币到其他货币。枚举拥有构造器,构造器传入汇率参数:
public enum ExchangeRate {
DOLLAR(6.2),
EURO(6.727),
WON(0.0057),
JPY(0.0518);
private double rate;
ExchangeRate(double rate) {
this.rate = rate;
}
public double getRate() {
return rate;
}
public double exchangedMany(double yuan) {
return yuan/rate;
}
}
枚举类型有强大的功能,如上示例。可根据如下代码换算出100元人民币对应其他货币值:
for(ExchangeRate rate : ExchangeRate.values()){
System.out.println(""+rate.exchangedMany(100));
}
枚举类型还可以在其内部定义抽象方法,并在具体值中实现。比如下面示例,其实我们也可以在枚举内部定义统一的方法getAnimators(View target,EffectHasDirection direction),通过Switch语言完成对应切换。通过Switch实现是有缺陷的,当增加新的枚举值时,Switch内容忘记更新,代码也可编译,只有在运行时才能找到错误。而下面这种方式的实现正好解决了这个问题,当用户添加新的枚举值时,必须实现枚举定义的抽象方法,把可能出现的故障停留在编译期。
public enum Direction {
TOP{
@Override
public Animator[] getAnimators(View target,EffectHasDirection direction) {
return direction.top(target);
}
},
RIGHT{
@Override
public Animator[] getAnimators(View target,EffectHasDirection direction) {
return direction.right(target);
}
},
BOTTOM{
@Override
public Animator[] getAnimators(View target,EffectHasDirection direction) {
return direction.bottom(target);
}
},
LEFT{
@Override
public Animator[] getAnimators(View target,EffectHasDirection direction) {
return direction.left(target);
}
};
public abstract Animator[] getAnimators(View target,EffectHasDirection direction);
}
以上代码,如果要增加新的枚举值,比如BOTTOM_LEFT,需要是这样的:
BOTTOM_LEFT{
@Override
public Animator[] getAnimators(View target,EffectHasDirection direction) {
return direction.bottomLeft(target);
}
},
总而言之,枚举与int,String枚举模式相比,优势是不言而喻的。枚举易读,更加安全,且功能更加强大。