一、为什么要学习枚举?
开发中有的时候我们是使用的数据或者对象是固定的几个,比如:返回码ErrorCode、四个季节等,这时候我们使用枚举类更合适。这里就有人想到了,为什么不用静态常量来替代枚举类呢?
例如我们描述季节也可以使用常量:
public static final int SPRING = 1;
public static final int SUMMER = 2;
public static final int FALL = 3;
public static final int WINTER = 4;
相比于静态的常量枚举类更加直观,类型更加安全。
使用常量会有以下几个缺陷:
- 类型不安全
若一个方法中要求传入季节这个参数,用常量的话,形参就是int类型,开发者传入任意类型的int类型值就行,但是如果是枚举类型的话,就只能传入枚举类中包含的对象。
- 没有命名空间
开发者要在命名的时候以SEASON_开头,这样另外一个开发者再看这段代码的时候,才知道这四个常量分别代表季节。
二、枚举类的使用
枚举是JDK1.5新增的一个特性,它使用关键字enum来定义。
跟我们定义class不一样的是,通常enum中的成员都是枚举类对象,并且默认省略了public static final定义,这也意味着我们使用枚举类的时候不需要创建枚举类对象直接调用即可。
枚举类的定义
下面我们先来定义一个简单的枚举类看下跟之前定义class有什么不同。
枚举类有以下几个特点:
-
enum和class、interface的地位一样
-
使用enum定义的枚举类默认继承了java.lang.Enum,而不是继承Object类,并且枚举类可以实现一个或多个接口。
-
枚举类的所有实例都必须放在第一行展示,不需使用new 关键字,不需显式调用构造器。自动添加public static final修饰。
-
使用enum定义、非抽象的枚举类默认使用final修饰,不可以被继承。
-
枚举类的构造器只能是私有的。
枚举类内也可以定义属性和方法,可以是静态的和非静态的。
实际上在第一行写枚举类实例的时候,默认是调用了构造器的,所以此处需要传入参数,因为没有写无参构造器,只能调用有参数的构造器。
枚举类的使用
枚举类通常是当做参数使用,Java5新增了enum关键字,同时扩展了switch,在switch…case结构中的case表达式中直接写入枚举值,且不需加入枚举类作为限定。
使用如下:
我们发现当使用枚举当做参数或者限定类型的时候,不仅可以让我们明确知道参数的类型保证了类型安全,也防止我们传入错误的数据。
三、枚举类实现接口
枚举类可以实现一个或多个接口。与普通类一样,实现接口的时候需要实现接口中定义的所有方法,若没有完全实现,那这个枚举类就是抽象的,只是不需显式加上abstract修饰,系统化会默认加上。
使用如下:
Operation枚举实际上是抽象的,不可以创建枚举值,所以此处在申明枚举值的时候,都重写了抽象方法,这其实是匿名内部类的实现,花括号部分是一个类对象。
如果我们去看下编译生产的class文件,
我们发现共生成了五个class文件,这样就证明了PLUS,MINUS,TIMES,DIVIDE是Operation的匿名内部类的实例。