简介:
enum是JAVA SE5中新添加的特性,关键字enum可以将一组具名的值的有限集合创建为一种新的类型(即枚举类)这些具名的值可以作为常规的程序组件使用。
首先看一个最简单的enum类:
public enum Color{
RED, GREEN, YELLOW
}
看起来像一个普通的类,据“一切皆对象”的宗旨来看,enum的确是一个“不普通”的类,事实上,在创建enum时,编译器会为你创建一个相关类,这个类继承自java.lang.Enum。Enum类实现了Compareable和Serializable接口。
enum的简单特性:
1.什么是枚举类
简介中介绍了:枚举类是一组具名的值的有限集合。那么其中具有的值是什么的,类除了自己的属性 & 方法(包括构造方法)就只剩下对象了。而上文中的Color枚举类中并无属性 & 方法,故此RED、GREEN、YELLOW这些“具名的值”实际上是类的对象。(这就是枚举类的特殊之处,在定义类的时候,类对象被同时定义封装了)。
而且这些枚举值(对象)都是常量的,即public static final 类型的。
想一下也是合情合理的。
枚举类就是外部访问的,public肯定是必须的;
枚举类的用途主要是为了区分有限集合的分类情况,并不主要用于实现什么功能,只需要为其他类提供引用即可。更何况在类定义的时候对象已经生成,因此static也是必要的;
枚举类是类构造者定义的,并不允许客户端程序员修改,因此final也是必要的。
画外音:按照命名惯例都用大写字母表示(多个单词中间用下划线隔开)
2.一个更加丰满的枚举类
既然枚举类是类,就可以有自己的成员变量、方法以及构造器。看下面的例子:
public enum Color{ RED("It's RED now ,stop crossing the road"), GREEN("It's GREEN ,you can go through"), YELLOW("It's YELLOW,you'd better wait for a while"); private String description; private Color(String description){ this.description = description; } public String getDescription(){ return description; } }
这里有几点需要稍稍留意一下:
a).如果你定义了自己的方法(包括构造器)则必须在enum实例序列的最后添加一个分号(注意:简单enum类是没有分号的)
b)自定义的方法(包含重写的方法) 和属性,必须写在enum实例之后,否则会编译错误
c)这里我们将构造器声明为private,其实我们只能在enum类的内部使用其构造器创建 枚举实例,一旦enum类定义结束,编译器就不允许我们在使用构造器来创建任何对象了,因此即便不声明为private对其访问性也没有任何区别(根据http://www.iteye.com/problems/81762所讲,构造器是可以声明为public的,但是eclipse还是报错了,不解)
d)enum类是final类型,无法被继承。
3.枚举类的常用方法
jd大神的博客中已经交代了,就不再啰嗦http://249326109.iteye.com/blog/1681605
4.switch中的enum
一直以为枚举跟switch是绝配,使用起来是非常方便的 ,这里copy一下jd的代码
package enumTest; public class EnumTest { enum Color { RED(255, 0, 0), BLUE(0, 0, 255), BLACK(0, 0, 0), YELLOW(255, 255, 0), GREEN( 0, 255, 0); // 构造枚举值,比如RED(255,0,0) private Color(int rv, int gv, int bv) { this.redValue = rv; this.greenValue = gv; this.blueValue = bv; } public String toString() { // 自定义的public方法 return super.toString() + "(" + redValue + "," + greenValue + "," + blueValue + ")"; } private int redValue; // 自定义数据域,private为了封装。 private int greenValue; private int blueValue; } public static void main(String args[]) { // Color colors=new Color(100,200,300); //错误,因为这个方法是私有的 Color color = Color.RED; System.out.println(color); // 调用了toString()方法 System.out.println(Color.BLACK.ordinal()); // values 方法返回 Color[] colors = Color.values(); for (Color c : colors) System.out.println(c); Color c = Color.RED; switch (c) { case RED: System.out.println("it's red"); break; case BLUE: System.out.println("it's blue"); break; case BLACK: System.out.println("it's blue"); break; } } }
值得注意的是:编译器并不要求switch中有default语句,也不要求每个枚举实例都有相应的case,所以要注意覆盖掉所有的分支。但是,如果在case语句中调用了return语句(无论是否覆盖所有的枚举实例),编译器就会要求default语句了。