大可制作:QQ群:31564239(asp|jsp|php|mysql)

Java Gossip: 简介枚举类型

常量设置 中,您知道可以在类(Class)或接口(Interface)中声明常量加以管理,这只是让您存取与管理常量方便而已,来看看这个例子:
public void someMethod() {
     ....
    doOp(OpConstants.TURN_RIGHT);
    ....
}
 
public void doOp(int op) {
    switch(op) {
        case OpConstants.TURN_LEFT:
            System.out.println("向左转");
            break;
        case OpConstants.TURN_RIGHT:
            System.out.println("向右转");
            break;
        case OpConstants.SHOOT:
            System.out.println("射击");
            break;
    }
}

看来是不错,但doOp()方法接受的是int,您没有阻止粗心的程序设计人员对它输入OpConstants中规定外的其它常量,您也没有检查 switch中枚举的值是不是正确的值,因为它骨子里就只是int而已。

当然您可以作一些检查,这需要一些额外的工作,如果您使用 J2SE 5.0,则这些额外的工作您不用亲自处理,使用枚举类型(Enumerated Types)可以轻易的解决这些问题。

在J2SE 5.0中使用枚举类型要使用"enum"关键字,以下先来看看枚举类型的应用,举个实际的例子:

  • OpConstants.java
public enum OpConstants {TURN_LEFT, TURN_RIGHT, SHOOT}

不用怀疑,在OpConstants.java中写下以上的内容,然后用javac去编译它,虽然语法上不像,但枚举类型骨子里就是一个类,所以您编译完成后,会产生一个OpConstants.class文件。

来看下面这个例子了解如何使用定义好的枚举类型:

  • Test.java
public class Test {
public static void main(String[] args) {
doOp(OpConstants.TURN_RIGHT);
}

public static void doOp(OpConstants opConstant) {
switch(opConstant) {
case TURN_LEFT:
System.out.println("向左转");
break;
case TURN_RIGHT:
System.out.println("向右转");
break;
case SHOOT:
System.out.println("射击");
break;
}
}
}

执行结果:
向右转

除了让您少打一些字之外,好像没有什么特别的,但如果您对doOp()方法输入其它的值,编译器会回报错误,因为doOp()所接受的是 OpConstants枚举类型。

更进一步的,如果您在switch中加入了不属于OpConstants中枚举的数值,编译器也会回报错误,例如:
....
    public static void doOp(OpConstants opConstant) {
        switch(opConstant) {
            case TURN_LEFT:
                System.out.println("向左转");
                break;
            case TURN_RIGHT:
                System.out.println("向右转");
                break;
            case SHOOT:
                System.out.println("射击");
                break;
            case STOP:
                System.out.println("停止");
                break;
        }
    }
 ....
 

编译器会替您作编译时期的检查,若检查出不属于OpConstant中的枚举值,会显示以下的错误:
unqualified enumeration constant name required
case STOP:
^

您可以在一个独立的文件中声明枚举值,或是在某个类中声明枚举成员,例如:

  • Test.java
public class Test {
private enum OpConstant {TURN_LEFT, TURN_RIGHT, SHOOT};

public static void doOp(OpConstant opConstant) {
switch(opConstant) {
case TURN_LEFT:
System.out.println("向左转");
break;
case TURN_RIGHT:
System.out.println("向右转");
break;
case SHOOT:
System.out.println("射击");
break;
}
}

public static void main(String[] args) {
doOp(OpConstant.TURN_LEFT);
}
}

由于枚举类型本质上还是个类,所以这种方式有些像在声明 内 部类(Iinner class), 在您编译完Test.java文件后,除了Test.class之外,您会有一些额外的.class文件,在这个例子中就是Test$ OpConstants.class与Test$1.class,看到后两个文件,您就应该了解到这个程序的背后运作的有内部成员类以及内部匿名类。