枚举通过enum关键字进行定义。实际上当定义一个枚举类型的时候,该类型默认继承了Enum类。
枚举的定义格式如下:
enum Color { RED,BLUE,GREEN; }
下面演示一个枚举变量的声明和输出:
1 public static void main(String[] args) throws Exception 2 { 3 Color c = Color.RED; 4 System.out.println(c); 5 }
当我们要遍历所有的枚举类型时,可以先将其转换为一个数组,然后用foreach语法进行输出。
1 public static void main(String[] args) throws Exception 2 { 3 Color[] colors = Color.values(); 4 for(Color color : colors) 5 { 6 System.out.println(color); 7 } 8 }
Enum类的构造函数如下:
1 Enum(String name, int ordinal)
因为所有的枚举类型都默认继承Enum,所以上面的代码实际上默认调用了该构造函数。name的值就是RED,BLUE或GREEN,而ordinal的值从0开始。所以,下面的代码演示了每个枚举变量的name和ordinal值。
1 public static void main(String[] args) throws Exception 2 { 3 Color[] colors = Color.values(); 4 for(Color color : colors) 5 { 6 System.out.println(color.ordinal() + ":" + color.name()); 7 } 8 }
输出结果为:
0:RED
1:BLUE
2:GREEN
我们在定义枚举类的时候,也可以定义构造函数。因为枚举类的实例必须是有限的个数(本文中Color中只有3种颜色),所以,构造函数必须私有化。
1 enum Color 2 { 3 RED("红色"),BLUE("蓝色"),GREEN("绿色"); 4 5 private String alias; 6 private Color(String alias) 7 { 8 this.alias = alias; 9 } 10 public String getAlias() 11 { 12 return this.alias ; 13 }18 }
因为定义了带参数的构造函数,所以在实例化枚举实例的时候,必须传入参数。
此时用下面的代码测试:
1 public static void main(String[] args) throws Exception 2 { 3 Color[] colors = Color.values(); 4 for(Color color : colors) 5 { 6 System.out.println(color.ordinal() + ":" + color.name() + "("+color.getAlias()+")"); 7 } 8 }
利用上面的特性,我们可以设计一个表示状态的枚举。如我们想定义一个会员状态的枚举类,会员状态有:待激活(0)、已激活(1)、锁定(-1)这三种状态。我们已经知道了,枚举变量有ordinal()方法可以提取该枚举变量的序号,然而这个数值只是代表该枚举序号,从0开始,显然无法表示-1,0,1这三种状态。这里可以借助构造方法来实现我们的需求:
1 enum MemberState 2 { 3 LOCKED(-1),READY(0),ACTIVED(1); 4 5 private Integer code ; 6 7 private MemberState(Integer code) 8 { 9 this.code = code; 10 } 11 12 public Integer getCode() 13 { 14 return this.code; 15 } 16 }
测试代码:
1 public class Main 2 { 3 public static void main(String[] args) 4 { 5 for(MemberState item : MemberState.values()) 6 { 7 System.out.println("序号:"+item.ordinal()); 8 System.out.println("状态:"+item.name()); 9 System.out.println("代码:"+item.getCode()); 10 System.out.println("----------"); 11 } 12 System.out.println("Main Done//~~"); 13 } 14 }
输出结果:
序号:0 状态:LOCKED 代码:-1 ---------- 序号:1 状态:READY 代码:0 ---------- 序号:2 状态:ACTIVED 代码:1 ---------- Main Done//~~
因为Enum实现了Comparable接口,所以可以对枚举类型排序:
1 public static void main(String[] args) throws Exception 2 { 3 Set<Color> colorSet = new TreeSet<Color>(); 4 colorSet.add(Color.BLUE); 5 colorSet.add(Color.GREEN); 6 colorSet.add(Color.RED); 7 for(Color color : colorSet) 8 { 9 System.out.println(color.ordinal() + ":" + color.name() + "("+color.getAlias()+")"); 10 } 11 }
输出结果:
0:RED(红色)
1:BLUE(蓝色)
2:GREEN(绿色)
我们也可以将一个字符串解析为枚举类型:
1 public static void main(String[] args) throws Exception 2 { 3 Color cRed = Color.valueOf("RED"); 4 Color cBlue = Color.valueOf("BLUE"); 5 System.out.println(cRed.ordinal() + ":" + cRed.name() + "("+cRed.getAlias()+")"); 6 System.out.println(cBlue.ordinal() + ":" + cBlue.name() + "("+cBlue.getAlias()+")"); 7 }
输出结果:
0:RED(红色)
1:BLUE(蓝色)