简介
枚举(enum)类型是java5新增的特性,是一中新的类型。在java编程思想中是这么介绍的:关键字enum可以将一组具名的值的有限集合创建为一中新的类型。
简单的说枚举可以方便的用来定义一组常量集。在jdk1.5之前定义常量都是:
public class Color{
public static final RED = 0;
public static final GREEN = 1;
public static final BLANK = 2;
public static final YELLOW = 3;
}
而有了枚举以后,可以这样:
public enum Color{
RED,GREEN,BLACK,YELLOW
}
创建enum的时候,编译器会为你生成一个相关的类,这个类继承自java.lang.Enum。所以enum是不能继承的。
下面代码展示了Enum提供的一些方法
package test;
enum Shrubbery{
GROUND,
CRAWLING,
HANGING
}
public class EnumClass {
public static void main(String[] args) {
for (Shrubbery s : Shrubbery.values()){
System.out.println(s + "ordinal:" + s.ordinal());
System.out.println("compareTo Shrubbery.CRAWLING:" + s.compareTo(Shrubbery.CRAWLING));
System.out.println("equals():" + s.equals(Shrubbery.CRAWLING));
System.out.println("==:" + (s == Shrubbery.CRAWLING));
System.out.println(s.getDeclaringClass());
System.out.println(s.name());
System.out.println("-------------------------------");
}
for (String s : "HANGING CRAWLING GROUND".split(" ")){
Shrubbery shrub = Enum.valueOf(Shrubbery.class, s);
System.out.println(shrub);
}
}
}
//输出:
GROUNDordinal:0
compareTo Shrubbery.CRAWLING:-1
equals():false
==:false
class test.Shrubbery
GROUND
-------------------------------
CRAWLINGordinal:1
compareTo Shrubbery.CRAWLING:0
equals():true
==:true
class test.Shrubbery
CRAWLING
-------------------------------
HANGINGordinal:2
compareTo Shrubbery.CRAWLING:1
equals():false
==:false
class test.Shrubbery
HANGING
-------------------------------
HANGING
CRAWLING
GROUND
ordinal()方法返回一个int值,这是每个enum实例在声明时的次序,从0开始。可以使用==来比较enum实例,编译器会自动为你提供equals()和hashCode()方法。Enum类实现了Comparable接口,所以具有compareTo()方法。getDirclaringClass()方法,我们就能知道其所属的enum类。name()方法返回enum实例声明时的名字,与toString()方法效果相同。valueOf是在Enum中定义的static方法,根据给定的名字返回相应的enum实例,如果不存在给定名字的实例,将会抛出异常。
使用
枚举有七种常见的用法
1.常量
就是我们一开始给出简单例子,可以定义一组常量集。
2.switch
JDK1.6之前的switch语句只支持int,char,enum类型,使用枚举,能让我们的代码可读性更强。
enum Color{
GREEN,
BLUE,
YELLOW
}
public class ColorClass {
public static void main(String[] args) {
Color color = Color.GREEN;
switch (color){
case BLUE:
System.out.println("color is blue");
break;
case GREEN:
System.out.println("color is green");
break;
case YELLOW:
System.out.println("color is yellow");
break;
}
}
}
不过有一点需要注意,在jdk1.7中switch语句可以支持String类型的参数,实际上,这个新特性是在编译器这个层次上实现的。而在 Java 虚拟机和字节代码这个层次上,还是只支持在 switch 语句中使用与整数类型兼容的类型。
3.向枚举中添加新方法
public enum OzWitch {
WEST("west"),
NORTH("north"),
EAST("east"),
SOUTH("south");
private String description;
private OzWitch(String description){
this.description = description;
}
public String getDescription(){
return description;
}
public static void main(String[] args) {
for (OzWitch witch : OzWitch.values())
System.out.println(witch + ":" + witch.getDescription());
}
}
我们可以向enum中添加方法,包括main()方法。需要注意的是:如果打算定义自己的方法,那么必须在enum实例序列的最后添加一个分号。同时,java要求必须先定义enum实例,否则报错。
4.覆盖enum方法
enum可以覆盖toString()方法。
enum Color{
GREEN,
BLUE,
YELLOW;
@Override
public String toString() {
String id = name();
String lower = id.substring(1).toLowerCase();
return id.charAt(0) + lower;
}
}
public class ColorClass {
public static void main(String[] args) {
for (Color c : Color.values()){
System.out.println(c);
}
}
}
5.实现接口
public interface Behaviour {
void print();
String getInfo();
}
public enum Color implements Behaviour{
RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
// 成员变量
private String name;
private int index;
// 构造方法
private Color(String name, int index) {
this.name = name;
this.index = index;
}
//接口方法
@Override
public String getInfo() {
return this.name;
}
//接口方法
@Override
public void print() {
System.out.println(this.index+":"+this.name);
}
}
所有的枚举都继承自java.lang.Enum类。由于Java 不支持多继承,所以枚举对象不能再继承其他类。
6.使用接口组织枚举
因为enum无法继承但我们又想通过使用积累将一个enum中的元素进行分组。这时我们可以在一个接口的内部,创建实现该接口的枚举,以此将元素进行分组,可以达到将枚举元素分类组织的目的。
public interface Food{
enum Appetizer implements Food{
SALAD, SOUP, SPRING_ROLLS;
}
enum MainCourse implements Food{
LASAGNE, BURRITO, PAD_THAI,
LENTILS, HUMMOUS, VINDALOO;
}
enum Dessert implements Food{
TIRAMISU, GELATO, BLACK_FOREST_CAKE,
FRUIT, CREME_CARAMEL;
}
enum Coffee implements Food{
BLACK_COFFEE, DECAF_COFFEE, ESPRESSO,
LATTE, CAPUCCINO, TEA, HERB_TEA;
}
}
7.EnumSet和EnumMap
java.util.EnumSet和java.util.EnumMap是两个枚举集合。EnumSet保证集合中的元素不重复;EnumMap中的key是enum类型,而value则可以是任意类型。关于这个两个集合的使用就不在这里赘述,可以参考JDK文档。
其他特征
java的enum有一个有趣的特征,即允许程序员为enum实例编写方法,是每个enum实例有各自不同的行为。
enum Color{
GREEN{
public String getInfo(){
return "color is green";
}
},
BLUE{
public String getInfo(){
return "color is blue";
}
},
YELLOW{
public String getInfo(){
return "color is blue";
}
};
abstract public String getInfo();
}
public class ColorClass {
public static void main(String[] args) {
for (Color c : Color.values()){
System.out.println(c.getInfo());
}
}
}
参考资料:
《java编程思想》
http://softbeta.iteye.com/blog/1185573