JAVA枚举类型

一、引言

在进行系统开发时,我们常会用数字或者字母去存储一些枚举项。比如用M表示男、F表示女,或者用1表示经理、2表示前台、3表示收银台、4表示厨房等等。但是如果在代码中出现:

if(type == "1"){
  ......
}else if(type == "2"){
  ...
}....
类似上述的代码,对于新员工或者系统维护人员来说,是一件非常头疼的事情。代码可读性非常低,而且很容易出错。

在JAVA SE5以下,JAVA语言并没有提供枚举类型,当时sun公司进行设计时,许多地方借鉴了C/C++语言,但是也取消了C/C++中部分数据类型,譬如枚举类型、结构体等。sun公司认为用普通类就可以完成枚举类型的功能。但是随着信息系统的日益壮大,sun公司又重新开始考虑枚举类型的必要性了。那么,我们先来利用普通类去实现枚举类型,体验一下枚举类型为我们带来的好处。

二、普通类实现枚举类型

假设我们要用MON、SUN表示周一和周日(周二~周六做法雷同),我们希望用Week.MON和Week.SUN进行调用。代码如下:

public class MyWeekEnum {
        private MyWeekEnum() { //防止new对象,即用户只能得到指定的类型
        }
        //实现用户只能得到MON和SUN
        public static MyWeekEnum MON = new MyWeekEnum();
        public static MyWeekEnum SUN = new MyWeekEnum();
}

public static void main(String[] args) {
	MyWeekEnum week = MyWeekEnum.MON;
	if (week == MyWeekEnum.SUN) {
		System.out.println("sun");
	} else if (week == MyWeekEnum.MON) {
		System.out.println("mon");
	} //输出为:mon
}
这样,一个最简单的枚举就写完了。接下来,我们考虑枚举类型是不是可以和其他普通类一样,有自己的方法。比如说我想知道明天是周几,即我想添加一个getNextDay()这样一个方法。我们可以这样实现:

public class MyWeekEnum {
	private MyWeekEnum() { // 防止new对象,即用户只能得到指定的类型

	}
	// 实现用户只能得到MON和SUN
	public static MyWeekEnum MON = new MyWeekEnum();
	public static MyWeekEnum SUN = new MyWeekEnum();

	public MyWeekEnum getNextDay() {
		if (this == MON) {
			return SUN;
		} else {
			return MON;
		}
	}
}
public static void main(String[] args) {
	MyWeekEnum week = MyWeekEnum.MON;
	System.out.println(week.getNextDay() == MyWeekEnum.MON); //falise
	System.out.println(week.getNextDay() == MyWeekEnum.SUN); //true
}

 
到目前为止,我们确实实现了枚举类型以及为枚举类型添加方法。但是由于枚举类型大家的地位是一样的,大家可能都希望能够自己去实现具体的方法,只希望 
MyWeekEnum能够提供一个"接口"告诉我需要实现哪些方法。而且如果用上述的方法去实现,一旦枚举类型的量大了,需要书写一大堆if...else,容易出错。于是我们进行了如下重构: 

public abstract class MyWeekEnum {
        private MyWeekEnum() { // 防止new对象,即用户只能得到指定的类型
	}

	// 实现用户只能得到MON和SUN
	public static MyWeekEnum MON = new MyWeekEnum() {
		@Override
		public MyWeekEnum getNextDay() { //具体实现
			return SUN;
		}
	};
	public static MyWeekEnum SUN = new MyWeekEnum() {
		@Override
		public MyWeekEnum getNextDay() { //具体实现
			return MON;
		}
	};

	public abstract MyWeekEnum getNextDay(); //抽象方法
}
这里需要注意的是MyWeekEnum需要定义成抽象类。MON和SUN变成了MyWeekEnum的子类,并重写父类方法,有点小多态的味道。最后,我们尝试一下在枚举类型里面添加常量。代码如下:

public abstract class MyWeekEnum {
	private MyWeekEnum() { // 防止new对象,即用户只能得到指定的类型

	}

	private MyWeekEnum(String describe) {
		this.describe = describe;
	}

	// 实现用户只能得到MON和SUN
	public static MyWeekEnum MON = new MyWeekEnum("周一") {
		@Override
		public MyWeekEnum getNextDay() {
			return SUN;
		}
	};
	public static MyWeekEnum SUN = new MyWeekEnum("周日") {
		@Override
		public MyWeekEnum getNextDay() {
			return MON;
		}
	};

	public abstract MyWeekEnum getNextDay();

	private String describe;

	public String getDescribe() {
		return this.describe;
	}
}
public static void main(String[] args) {
	MyWeekEnum week = MyWeekEnum.MON;
	System.out.println(week.getDescribe()); //周一
}
三、枚举类型使用
在第二小节中,我们实现了JAVA枚举类型大部分常见的功能。相信如果了解了第二小节的内容再看JAVA的枚举类型会轻松不少。首先,我们来看看JAVA的枚举类型是如何定义的:

public enum Week {
	MON,SUN;
}
这样一个枚举就定义好了,调用方式:Week.SUN、Week.MON,是不是觉得非常方便呢?其实,我们在创建enum时,编译器会为你生成一个相关的类,这个类继承自java.lang.Enum(所以enum类型不能再继承其他类了,但是可以实现其他多个接口),它自带了一些方法,接下来我们去研究一下这些方法。

1、values()  它可以返回enum实例的数组,而且他们的下标就是我们声明的顺序。

2、name()  它返回enum实例声明时的名称。

for (Week w : Week.values()) {
	System.out.println(w.name());
}//输出为:MON SUN

3、ordinal()  它返回一个int,是每一个enum实例在声明时的次序,从0开始编号。

4、getDeclaringClass()  它可以返回enum实例所属的enum类。

5、valueOf()  它会根据给定的名称返回相应的enum实例,多用于web开发中,我们接收web前端提交的字符串,去生成一个enum实例。

Week week = Week.valueOf("MON"); // 模拟从web前端取到MON字符串
System.out.println(week.name() + " " + week.getDeclaringClass()); //MON class edu.fjnu.test.Week

接下来我们来看看在enum中添加方法。其实和我们上述的实现大同小异。

public enum Week {
	MON(){
		@Override
		public Week getNextDay() {
			return SUN;
		}
	}, 
	SUN(){
		@Override
		public Week getNextDay() {
			return MON;
		}
	};
	public abstract Week getNextDay();
}
最后我们来看看枚举类型如何实现带参构造函数:

public enum Week {
	MON("周一") {
		@Override
		public Week getNextDay() {
			return SUN;
		}
	},
	SUN("周日") {
		@Override
		public Week getNextDay() {
			return MON;
		}
	};
	private Week() {
	}

	private Week(String describe) {
		this.describe = describe;
	}

	public abstract Week getNextDay();

	private String describe;

	public String getDescribe() {
		return this.describe;
	}
}
public static void main(String[] args) {
	Week week = Week.valueOf("MON"); // 模拟从web前端取到MON字符串
	System.out.println(week.name() + " " + week.getDescribe()); //MON 周一
}
枚举类型基本的用法大致就介绍到这里,欢迎大家围观吐槽!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值