天天看点

使用enum关键字创建枚举类

语法(定义)

使用enum关键字创建枚举类型,隐含了所创建的类型都是 java.lang.Enum 类的子类(java.lang.Enum 是一个抽象类)。枚举类型符合通用模式 Class Enum<E extends Enum<E>>,而 E 表示枚举类型的名称。枚举类型的每一个值都将映射到 protected Enum(String name, int ordinal) 构造函数中,在这里,每个值的名称都被转换成一个字符串,并且序数设置表示了此设置被创建的顺序。

public enum EnumTest {

    MON, TUE, WED, THU, FRI, SAT, SUN;

}

这段代码实际上调用了7次 Enum(String name, int ordinal):

new Enum<EnumTest>("MON",0);

new Enum<EnumTest>("TUE",1);

new Enum<EnumTest>("WED",2);

    ... ...

遍历、switch 等常用操作

for (EnumTest e : EnumTest.values()) {

                   System.out.println(e.toString());

}

 EnumTest test = EnumTest.TUE;

switch (test) {

                 case MON:

                     System.out.println("星期一");

                     break;

                 case TUE:

                     System.out.println("星期二");

                     break;

                 // ... ...

                 default:

                     System.out.println(test);

                     break;

        }

原理分析:

enum 的语法结构尽管和 class 的语法不一样,但是经过编译器编译之后产生的是一个class文件。该class文件经过反编译可以看到实际上是生成了一个类,该类继承了java.lang.Enum<E>。EnumTest 经过反编译(javap com.test.EnumTest 命令)之后得到的内容如下:

public class com.test.EnumTest extends java.lang.Enum{

    public static final com.test.EnumTest MON;

    public static final com.test.EnumTest TUE;

    public static final com.test.EnumTest WED;

    public static final com.test.EnumTest THU;

    public static final com.test.EnumTest FRI;

    public static final com.test.EnumTest SAT;

    public static final com.test.EnumTest SUN;

    static {};

    public int getValue();

    public boolean isRest();

    public static com.test.EnumTest[] values();

    public static com.test.EnumTest valueOf(java.lang.String);

    com.test.EnumTest(java.lang.String, int, int, com.test.EnumTest);

}

所以,实际上 enum 就是一个 class,只不过 java 编译器帮我们做了语法的解析和编译而已。另外,enum 不能使用 extends 关键字继承其他类,因为enum已经继承了 java.lang.Enum(java只支持单一继承)。

枚举类的属性:

枚举类对象的属性不应允许被改动, 所以应该使用 private final 修饰。

1)枚举类的使用 private final 修饰的属性应该在构造器中为其赋值。

2)若枚举类显式的定义了带参数的构造器, 则在列出枚举值时也必须对应的传入参数。

枚举类的主要方法:

values()方法:返回枚举类型的对象数组。该方法可以很方便地遍历所有的枚举值。

valueOf(String str):可以把一个字符串转为对应的枚举类对象。要求字符串必须是枚举类对象的“名字”。如不是,会有运行时异常。

getDeclaringClass():返回与此枚举常量的枚举类型相对应的 Class 对象。

name():返回此枚举常量的名称,在其枚举声明中对其进行声明。

ordinal():返回枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)。

toString():返回枚举常量的名称,它包含在声明中。

示例:

public class Seasons {

      public static void main(String[] args) {

Season1 spring = Season1.SPRING;

System.out.println(spring);// 默认调用spring.toString()方法

System.out.println(spring.getSeasonName());

spring.show();

//使用values()方法可以返回整个枚举类的对象

Season1[] seasons = Season1.values();

for(Season1 s : seasons){

      System.out.println(s);

}

//使用valueOf(String str)

String str = "SPRING";

Season1 season = Season1.valueOf(str);

System.out.println(season);

     }

}

interface Info{

void show();  

}

enum Season1 implements Info {

      SPRING("SPRING", "春天") {

public void show() {

System.out.println("春暖花开");

}

      },

      SUMMER("SUMMER", "夏天") {

public void show() {

System.out.println("夏日炎炎");

}

      },

      AUTUMN("AUTUMN", "秋天") {

public void show() {

System.out.println("秋高气爽");

}

      },

      WINTER("WINTER", "冬天") {

public void show() {

System.out.println("白雪皑皑");

}

      };

      // 1.提供类的属性,并声明为private final

      private final String seasonName;

      private final String seasonDesc;

      // 2.将声明为private final的属性在私有化的构造器中初始化

      private Season1(String seasonName, String seasonDesc) {

this.seasonName = seasonName;

this.seasonDesc = seasonDesc;

      }

      // 3.通过公共的方法来调用私有属性

      public String getSeasonName() {

return seasonName;

      }

      public String getSeasonDesc() {

return seasonDesc;

      }

      @Override

      public String toString() {

return "Season1 [seasonName=" + seasonName + ", seasonDesc="

+ seasonDesc + "]";

      }

      public void show() {

System.out.println("这是一个季节!");

      }

}