以前的Java是没有枚举的,凡是需要用的时候大家都是用具名int常量来做,于是我们经常能看到类的成员变量有一堆密密麻麻的public static final int,但使用这种整数常量来代替其实会有一些问题,比如:
- 当我们得到了一个枚举的状态,想打印出状态时我们只能看到一个数字,要想知道这数字是啥意思还得查;
- 当我们使用这个状态时,有些程度员可能图方便用数字来填,有可能这数字完全不在枚举之列编译也不会发现,比如Toast.makeText(context,"hello",0).show()你把0换成-100也可以,但是-100显然不是正确的枚举;
- 当我们用整数来枚举时,得“编”一些数字码,而有时候就会编出重复的东西但也不会报错,比如,今天我写了一个状态码叫STATUS_READY=0X12,第二天我同事没仔细看我的代码变动,又添加了一个状态码STATUS_RESUME=0X12,这就会引发潜在的错误。
好了,枚举类能比较好的解决上述问题,下面就我想到的使用简单总结一下。
首先,是最简单的枚举类型
public enum WeekDay{
SUN,MON,TUE,WED,THU,FRI,SAT
}
然后我们看一个接收字符串来转换成枚举并使用的例子:
public class EnumDemo {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
System.out.println("enter a weekday in three letters");
String weekdayString=scanner.nextLine();
scanner.close();
WeekDay weekdayEnum = null;
try {
weekdayEnum = WeekDay.valueOf(weekdayString.toUpperCase());
} catch (IllegalArgumentException e) {
System.out.println("invalid weekday!");
}
System.out.println(weekdayEnum.name()+" - rank in declaration:"+weekdayEnum.ordinal());
switch (weekdayEnum) {
case SUN:
// do something
break;
case MON:
break;
case TUE:
break;
case WED:
break;
case THU:
break;
case FRI:
break;
case SAT:
break;
default:
break;
}
}
public enum WeekDay{
SUN,MON,TUE,WED,THU,FRI,SAT
}
}
测试一下,运行后输入sat,打印结果为:
enter a weekday in three letters
sat
SAT - rank in declaration:6
这里其实想强调的是枚举类型有一个静态方法valueOf()可以将字符串转换成此类型的枚举。
sat
SAT - rank in declaration:6
这里其实想强调的是枚举类型有一个静态方法valueOf()可以将字符串转换成此类型的枚举。
如果我们有时候想用整数呢?那我们也可以把整数转换成枚举类,下面看这个例子:
public class EnumDemo {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
System.out.println("enter a weekday in number,from zero on");
int num=scanner.nextInt();
System.out.println("result is "+WeekDay.values()[num]);
scanner.close();
}
public enum WeekDay{
SUN,MON,TUE,WED,THU,FRI,SAT
}
}
运行后输入2,打印结果为:
enter a weekday in number,from zero on
2
result is TUE
2
result is TUE
如果想把枚举换成整数码呢,比如要把状态换成一个数字代码,那我们可以用
weekDay.ordinal()
这个方法其实代表的是他在枚举列表中的排行(从0开始),不过这个方法来表示一个状态码也不错嘛。
如果想把这个状态码还原回枚举,就用
WeekDay.values()[num]
枚举的静态方法values()会返回一个数组,包含这个枚举中所有的枚举值,然后我们用这个数字码也即排号就能拿到对应的枚举值了。
看到这里小伙伴们可能要喷我了,我们的枚举代码表可不是从0开始排序那么简单原始的,好吧,没关系,如果这样也不是不能用枚举嘛,下面看看如何用写显示构造方法的枚举来实现枚举与任意整数挂钩:
public class EnumDemo {
public static void main(String[] args) {
//整数转枚举
int code=56;
System.out.println(WeekDay.getWeekDay(code));
//枚举转整数
WeekDay weekday=WeekDay.FRI;
System.out.println(weekday.dayCode);
}
public enum WeekDay{
SUN(121),MON(78),TUE(56),WED(33),THU(13),FRI(9),SAT(6);
private int dayCode;//记录枚举对应的数字码
private WeekDay(int dayCode){
this.dayCode=dayCode;
}
public static WeekDay getWeekDay(int dayCode){
for(WeekDay weekday:WeekDay.values()){
if(dayCode==weekday.dayCode){
return weekday;
}
}
return null;
}
}
}
其实,枚举也是java类,但是其构造方法必须是私有的,我们可以在列举枚举时使用带参数的构造方法,并把参数放到枚举类里,这里其实有个小问题其实我也没明白,WeekDay里面的成员变量dayCode明明是private的,但在main方法里面仍然可以访问到……希望知道原因的童鞋不吝指点。
下面再说说给枚举加方法,这个就和普通的类方法差不多了,就是要灵活运用枚举的几个重要方法,下面来写例子,还上那个WeekDay,实现一个方法,返回第二天的WeekDay,上代码:
public class EnumDemo {
public static void main(String[] args) {
WeekDay day=WeekDay.SAT;
System.out.println(day.nextDay());
day=WeekDay.THU;
System.out.println(day.nextDay());
}
public enum WeekDay{
SUN,MON,TUE,WED,THU,FRI,SAT;
public WeekDay nextDay(){
if(ordinal()==WeekDay.values().length-1)
return SUN;
else
return WeekDay.values()[ordinal()+1];
}
}
}
最后再说一种用法,就是带抽象方法的枚举……囧,这种用法比较诡异,但确实是可以这么来的,下面举例,还是那个WeekDay,带一个抽象的得到全名称的方法,上代码:
public class EnumDemo {
public static void main(String[] args) {
WeekDay day=WeekDay.MON;
System.out.println(day.getFullName());
}
public enum WeekDay{
SUN {
@Override
public String getFullName() {
return "Sunday";
}
},MON {
@Override
public String getFullName() {
return "Monday";
}
},TUE {
@Override
public String getFullName() {
return "Tuesday";
}
},WED {
@Override
public String getFullName() {
return "Wednesday";
}
},THU {
@Override
public String getFullName() {
return "Thursday";
}
},FRI {
@Override
public String getFullName() {
return "Friday";
}
},SAT {
@Override
public String getFullName() {
return "Saturday";
}
};
public abstract String getFullName();
}
}
好了,目前就只能想到这些种用法,如果你在实战中还发现有其他有趣的用法,请留言给我,大家一起学习哦!