枚举是java 5新增了一个menu关键字(它与class、interface关键字的地位相同),用于定义枚举,枚举是一种特殊的类,它一样有自己的Fileld、方法,可以实现一个或多个接口,也可以定义自己的构造器。一个java源文件中最多只能定义一个public访问权限的枚举类,且该java源文件也必须和枚举类的类名相同。
定义
枚举是指一组固定常量组成合法值的类型。
性质
枚举是真正的 final,客户端不允许创建枚举类的实例,也不能对其进行拓展。
Java 枚举本质上是 int 值。只能通过公有的静态 final 域为枚举类导出实例。
public enum Color {
GREEN,RED,BLUE,GRAY;
}
实际上枚举的完整的结构为:
public enum Color {
GREEN,RED,BLUE,GRAY;
Color() {
}
如果在 Color() 构造方法之前加上 private 则不会有任何问题。如果加上 public 等修饰符,IDE 会报错,也就是编译器不会通过。其实这是枚举与类的根本区别,就在于构造方法私有。
当然如果仅仅是构造方法私有,不再提供构造方法了,也就是说外界不能 new 实例,如果仅从这样看,那枚举就没有什么用了。
其实我们用过枚举的都知道,GREEN、RED 都是 Color 型的实例,其实枚举也可以看作自动处理了一些东西,帮助简化了代码,翻译成类大致就是:
public class Color {
public static final Color GREEN = new Color(),
RED = new Color(),
BLUE = new Color(),
GRAY = new Color();
private Color() {
}
}
如果从这种角度去看,枚举的用法就不难理解了,也就是枚举类不给外界实例化的机会,只能它自己实例化,而一个枚举类的所有实例就只有枚举前面分号前的那几个,其他地方不允许创建。
与普通类的异同
相同点
- 均可以实现接口
不同点
- 枚举类可以实现一个活多个接口,使用menu定义的枚举直接继承了java.long.Enum类,而不是继承Object类。其中java.long.Enum类实现了java.long.Serializable和java.long.Comparable两个接口。
- 使用enum定义、非抽象的枚举默认修饰符为final,因此枚举不能派生子类。
- 枚举的构造器只能使用private访问控制符,如果省略了枚举的访问修饰符其默认为private修饰;如果加强制定访问修饰符则只能使用private。
- 枚举的所有实例必须在枚举的第一行显示列出,否则这个枚举永远都不能生产实例,列出这些实例时系统会自动添加public static final修饰,无需程序员显式添加。
- 所有的枚举类都提供了一个values方法,该方法可以很方便的遍历所有的枚举值。
- 常量值地址唯一,可以用==直接对比,性能会有提高。