在java SE5中添加了一个很有用的特性,即enum关键字。它使得我们在需要群组并使用枚举类型集的时候,可以很方便的处理。在此之前,你需要创建一个整型常量集。而使用enum,我们能很方便的把一组 具名的值创建为一种新的类型。这实在是一种很方便的功能。
枚举是一种我们用的很多,但是其实对它并不是很理解的一个关键字。就如string,大家都在用,可还是很多同学不知道,string并不是基本类型,而只是一个类。而且string不能被继承。因为string是一个final类。枚举其实也是一样的。enum也是一个类。大家可以看看代码里的enum定义:
- Public abstract class Enum<E extends Enum<E>> implements Serializable,Comparable <E>
- {
- ...
- }
可以看出,enum也只是一个普通的抽象类而已。但是enum又不普通。说它普通是因为,它仅仅是一个普通抽象类,可以添加任意方法,包括私有构造器(虽然私有和公有在enum中无本质区别)。大家看源码就知道了。说它不普通是因为这个类是不允许继承与被继承的。为什么呢?
因为编译器在我们定义的时候,就将我们定义的enum对象类继承自enum类了,由于已经继承了一个enum类,根据java的单继承机制,我们是无法再继承另外的类的。那么为什么不能被继承呢?因为编译器会将它编译成final类(与string)一样。这样它就不能被继承了。
说到这里,大家可能还不太了解,没关系,我们来写一个简单的例子。
- enum Explore {HERE, THERE }
这是大家常用的方式,都很熟,也很理解。好的,我们用反编译来看看
- final class Explore extends java.lang.Enum{
- public static final Explore HERE;
- public static final Explore THERE;
- public static final Explore[] values();
- public static Explore valueOf(java.lang.String);
- static();
- }
以上只是enum的简要介绍,下面我们来看一个稍微有点意思的一种用法,也就是我前面提到的,enum是一个类,并且你可以自定义构造器。下面我们来看看android的这种用法。
源码路径:
frameworks/base/policy/src/com/android/internal/policy/impl/GlobalActions.java
- private static abstract class ToggleAction implements Action {
- enum State {
- Off(false);
- TurningOn(true);
- ...
- }
- state(boolean intermediate) {
- inTransition = intermediate;
- }
- ...
- }
可以看到,这就是在我们定义的enum类型中加入了自定义构造器。在我们定义这些类型的时候,调用构造器完成了自定义的动作(比如本例中的赋值)。这实在是一种很精妙的用法。大家可以下去深究。
另外,在enum类中,也可以加入自定义的元素。比如变量或者方法。例如本例中的inTransition变量和构造器。但是一定要确保它们在enum的序列之后添加,并且最后一个元素之后要添加一个;号,否则会编译错误。
关于enum,本文只是简单的加以分析,稍带点android的源码。enum的更高级特性,不做深究。