Contents
  1. 1. 语法(定义)
  2. 2. 遍历、switch 等常用操作
  3. 3. enum 对象的常用方法介绍
  4. 4. 给 enum 自定义属性和方法
    1. 4.1. EnumTest.java文件:
    2. 4.2. Lianxix.java文件:
    3. 4.3. EnumTest.java文件:
    4. 4.4. lianxix.java文件:
  5. 5. 神秘的values()

参考:http://www.cnblogs.com/hemingwang0902/archive/2011/12/29/2306263.html
《Thinking in java》

语法(定义)

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

1
2
3
4
5
6
7
8
9
10
package com.hmw.test;

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 等常用操作

对enum进行遍历和switch的操作示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class Test {
public static void main(String[] args) {
for (EnumTest e : EnumTest.values()) {
System.out.println(e.toString());
}

System.out.println("----------------我是分隔线------------------");

EnumTest test = EnumTest.TUE;
switch (test) {
case MON:
System.out.println("今天是星期一");
break;
case TUE:
System.out.println("今天是星期二");
break;
// ... ...
default:
System.out.println(test);
break;
}
}
}
输出结果:
MON
TUE
WED
THU
FRI
SAT
SUN
----------------我是分隔线------------------
今天是星期二

enum 对象的常用方法介绍

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
int compareTo(E o) 
比较此枚举与指定对象的顺序。
Class<E> getDeclaringClass()
返回与此枚举常量的枚举类型相对应的 Class 对象。
String name()
返回此枚举常量的名称,在其枚举声明中对其进行声明。
int ordinal()
返回枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)。
String toString()
返回枚举常量的名称,它包含在声明中。
static <T extends Enum<T>> T valueOf(Class<T> enumType, String name)
返回带指定名称的指定枚举类型的枚举常量。
public class Test {

public static void main(String[] args) {
EnumTest test = EnumTest.TUE;

//compareTo(E o)
switch (test.compareTo(EnumTest.MON)) {
case -1:
System.out.println("TUE 在 MON 之前");
break;
case 1:
System.out.println("TUE 在 MON 之后");
break;
default:
System.out.println("TUE 与 MON 在同一位置");
break;
}

//getDeclaringClass()
System.out.println("getDeclaringClass(): " + test.getDeclaringClass().getName());

//name() 和 toString()
System.out.println("name(): " + test.name());
System.out.println("toString(): " + test.toString());

//ordinal(), 返回值是从 0 开始
System.out.println("ordinal(): " + test.ordinal());
}
}
输出结果:
TUE 在 MON 之后
getDeclaringClass(): com.hmw.test.EnumTest
name(): TUE
toString(): TUE
ordinal(): 1

给 enum 自定义属性和方法

  除了不能继承自一个enum之外,我们基本上可以将enum看作一个常规的类。也就是说我们可以向enum中添加方法和属性,或覆盖enum的方法。

例1:

EnumTest.java文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package lianxi;

public enum EnumTest {
MON("xingqiyi"),
TUE("xingqier");//这里添加了一个分号

String description;

private EnumTest(String description){
this.description = description;
}

public String getDescription(){
return description;
}
}

Lianxix.java文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package lianxi;

import java.util.*;
import java.io.*;


public class lianxix{

public static void main(String[] args)
{

for(EnumTest e : EnumTest.values()){
System.out.println(e + ": " + e.getDescription());
}
}
}

输出:
MON: xingqiyi
TUE: xingqier

例2:

EnumTest.java文件:

1
2
3
4
5
6
7
8
9
10
11
package lianxi;

public enum EnumTest {
DABAI,DATONG;

public String toString(){
String id = this.name();//获得此枚举常量的名字
String lower = id.substring(1).toLowerCase();//第一个字母大写其他小写
return id.charAt(0) + lower;
}
}

lianxix.java文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package lianxi;

import java.util.*;
import java.io.*;


public class lianxix{

public static void main(String[] args)
{

for(EnumTest e : EnumTest.values()){
System.out.println(e);
}
}
}

说明:
  如果你打算定义自己的方法,那么必须在enum实例序列的最后添加一个分号。同时java要求必须先定义enum实例。
  enum中的构造器和方法和普通类除了有少许限制外没啥大的区别,enum就是一个普通类,在例1中我们有意识地将enum的构造器声明为private,但其实不声明也为private,因为我们只能在enum定义的内部使用其构造器创建enum实例。一旦enum的定义结束,编译器就不允许我们再使用其构造器来创建任何实例了。

神秘的values()

  《Thinking in java》里用反射的方法分析了这个values()的由来,这里只作简单说明。 Values()方法是由编译器插入到enum定义的static方法,所以,如果将enum实例向上转型为Enum,那么vaules()方法就不可以访问了,不过,在Class中有一个getEnumConstants()方法,所以即使Enum接口中没有vaules()方法,我们仍然可以通过Class对象取得所有enum实例。

1
2
3
4
5
6
7
8
public static void main(String[] args)   
{

EnumTest[] vals = EnumTest.values();
Enum e = EnumTest.DABAI;
//e.values(); NO values() in Enum
for(Enum en : e.getClass().getEnumConstants())
System.out.println(en);
}

补:getEnumConstants()是Class上的方法,所以甚至可以对不是枚举的类调用此方法。

Contents
  1. 1. 语法(定义)
  2. 2. 遍历、switch 等常用操作
  3. 3. enum 对象的常用方法介绍
  4. 4. 给 enum 自定义属性和方法
    1. 4.1. EnumTest.java文件:
    2. 4.2. Lianxix.java文件:
    3. 4.3. EnumTest.java文件:
    4. 4.4. lianxix.java文件:
  5. 5. 神秘的values()