为什么要使用枚举,枚举为何被称为语法糖

为什么要用枚举呢?

在JDK1.5之前,Java有两种方式定义新类型:类和接口。对于大部分面向对象编程来说,这两种方法看起来似乎足够了。但是在一些特殊情况下,这些方法就不适合。例如,想定义一个Color类,它只能有RED、GREEN、BLUE 3种值,其他的任何值都是非法的,那么JDK1.5之前虽然可以构造这样的代码,但是要做很多的工作,就可能带来很多不安全的问题。而JDK1.5之后引入的枚举类型就能解决这些问题。


什么是枚举呢?

枚举,在数学上是指有穷序列集,就是说某一类东西,能一一列出来。比如月份,可以有一月、二月……十二月,不能再多了,星期也是一样的概念。先声明,如果只是简单的穷举,除了语义更明确,我没觉得用“枚举”来替代“一个接口定义几个常量”这种方式有什么其他优势,只有被穷举的对象有一定业务性导致其具有一定复杂性,枚举才体现其简约。

枚举还有一个特点,就是可以代表数值,比如说第一个定义的元素对应的值为0,每个枚举元素从0开始,逐一增加。此时,这个数值也代表他们本身,相当于每一个元素有两个名字。

###


什么时候使用呢

1、一周有多少天?

7天。像这样固定不变的一组数据,如果我们的程序有需要用到这“7天”的相关信息,例如:发工资分为工作日和周末,可以考虑使用枚举类型。

2、太阳系有多少个行星?

8个。当我们需要计算每个行星的表面重力的时候,像这样我们需要用到固定不变的一组信息中的每一个元素携带了不同的信息,可以考虑使用枚举类型。

3、计算器中的基础运算符。

加减乘除。像这样我们需要用到固定不变的一组信息中的每一个元素都决定了不同的行为的时候,可以考虑使用枚举类型。

4、web请求返回的状态。

比如:error为-1,success为0,未登录为-9等可以设为枚举类型。


为什么说枚举是语法糖呢?

假如我们要定义季节类,包含一个季节名称和执行计划,没有枚举之前我们也许是这样做的

定义一个父类

public abstract class Weather {
	public String name;
	abstract void  plan();
}

定义春天

public class SpringWeather extends Weather{
	public SpringWeather(String name) {
		this.name=name;
	}

	@Override
	void plan() {
		System.out.println("春天");
	}
}

定义夏天

public class SummerWeather extends Weather{
	public SummerWeather(String name) {
		this.name=name;
	}

	@Override
	void plan() {
		System.out.println("夏天");
	}

}

定义秋天,定义冬天…….

如上加上我们省略掉的,要穷举季节这样一个具有一定复杂性的有穷序列集,我们要写多个类,JAVA语法真啰嗦!有了枚举之后我们可以这样写:

public enum WeatherEnum {

	SPRING(1, "春天") {
		@Override
		void plan() {
			System.out.println("春天");
		}
	},

	SUMMER(2, "夏天") {
		@Override
		void plan() {
			System.out.println("夏天");
		}
	},

	AUTUMN(3, "秋天") {
		@Override
		void plan() {
			System.out.println("秋天");
		}
	},


	WINTER(4, "冬天") {
		@Override
		void plan() {
			System.out.println("冬天");
		}
	};

	private Integer num;

	private String name;

	private WeatherEnum(Integer num, String name) {
		this.num = num;
		this.name = name;
	}


	public Integer getNum() {
		return num;
	}


	public void setNum(Integer num) {
		this.num = num;
	}


	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}


	abstract void plan();

	@Override
	public String toString() {
		return "num:" + this.num + "  name:" + this.name;
	}
}

只需要enum关键字定义一个类就可以代替上面的多个类,确实简约!

事实上现实中的业务比季节这个概念要复杂些,没有枚举的话可能还需要更多的类定义,比如季节里面的计划,我们现在仅仅是简单地输出一句话而已。 以上便是JAVA枚举语法糖的一个优势,既然是语法糖,也就是说,只是看起来是这样子,事实上枚举定义编译后,也是被编译成了多个class。这个可以查看编译后的class文件就知道了!

img

可以看出,使用枚举能使我们减少类的定义,并且语义明确,使用面向对象的说法就是枚举实现了代码复用。

img

再查看一下反编译后的类,发现类都是被static修饰的,当我们使用enmu来定义一个枚举类型的时候,编译器会自动帮我们创建一个final类型的类,所以枚举类型不能被继承.