基本enum特性

当创建一个enum的时候,编译器会生成一个相关的类,这个类继承于java.lang.Enum。

1
2
3
4
public enum Season
{
SPRING, SUMMER, AUTUMN, WINTER
}

Enum类提供了一些方法如下:

  • int ordinal() 返回枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)。
  • Class getDeclaringClass() 返回与此枚举常量的枚举类型相对应的 Class 对象。
  • int compareTo(E o) 比较此枚举与指定对象的顺序。
  • <T extends Enum<T>> T valueOf(Class<T> enumType, String name) 返回带指定名称的指定枚举类型的枚举常量。

向enum中添加新方法

除了不能继承自一个enum之外,基本上可将enum看作为一个常规的类。如果在enum当中自定义方法,那么必须在enum实例序列的最后添加一个分号。同时,方法必须在实例之后定义。

如下例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public enum Season
{
SPRING("春"), SUMMER("夏"), AUTUMN("秋"), WINTER("冬");

private String name;

private Season(String name)
{
this.name = name;
}

public String getName()
{
return name;
}
}

在这个例子当中,虽然我们把构造器声明为private,但是对于它的可访问性而言,其实没什么变化,因为即使不声明为private,我们也只能在enum定义的内部使用其构造函数创建enum实例。一但enum的定义结束,编译器不允许我们再使用构造器来创建任何实例了。

switch语句中的enum

一般switch中只能使用整数值,在jdk7可以支持了字符串,但是枚举就可以用在switch语句中。

1
2
3
4
5
6
7
8
9
10
11
12
13
Season season = Season.WINTER;
switch (season)
{
case WINTER:
System.out.println("WINTER");
break;
case SUMMER:
System.out.println("SUMMER");
break;
default:
System.out.println("default");
break;
}

这里需要注意的是,一般情况下我们需要使用enum类型来修饰enum的实例,但是在case当中是不需要的。

还有需要注意的是,如果season是null的话这个地方会报空指针异常。原因很简单,因为编译的时候,编译器会判断出switch语句后的参数是枚举类型,然后会根据枚举的排序值继续匹配,也就是说上面的代码与下面的代码相同:

1
2
3
4
5
6
7
8
9
10
11
12
switch (season.ordinal())
{
case Season.WINTER.ordinal():
System.out.println("WINTER");
break;
case Season.SUMMER.ordinal():
System.out.println("SUMMER");
break;
default:
System.out.println("default");
break;
}

当然上面的代码是编译不能通过的,因为case后面必须跟一个常量值。但是可以看出switch当中需要先计算枚举的排序,如果为null则会出现空指针异常的。

values() 方法

当创建enum类的时候,编译器会自动继承Enum类。但是在Enum类中我们没有看到values()方法。values()方法是编译器添加的static方法,同时还添加了valueOf()方法。

由于values()方法是编译器动态添加上去的,所以将enum实例向上转型为Enum,那values()方法就会不可以访问。不过,在Class类当中有个方法getEnumConstansts()方法,也可以获取到所有的enum实例。

由于enum都是继承于Enum类的,并且java不支持多继承,所以enum不能继承其他类,但是可以实现一个或者多个接口。

EnumSet

EnumSet是与枚举类型一起使用的专用 Set 实现。EnumSet中所有键都必须来自单个枚举类型。

EnumSet在内部表示为位向量。通常用于替代传统上基于 int 的“位标志”,具有高品质、类型安全的优势。由于EnumSet的内部基于一个long变量,并且是基于位的操作运算,long类型占64个bit位,这个位数的占用是根据enum的序号有关系的,所以如果enum的实例个数少于64个性能会非常的快。

EnumMap

EnumMap是与枚举类型键一起使用的专用 Map 实现。枚举映射中所有键都必须来自单个枚举类型。

—EOF—