本文介绍JAVA SE5中枚举的使用
一、概念
关键字enum可以将一组具名值的有限集合创建为一种新的类型,而这些具名可以作为常规的程序组件使用。
二、向枚举中添加新方法
1、示例
package net.oschina.tkj.chapter19.enumclass;
/**
* 枚举类中添加方法 注意:先定义枚举类实例,最后一个实例要用分号隔开
* name(),toString()方法返回枚举类实例名称,添加枚举类构造器可以返回额外信息
*
* @author Freedom
*
*/
public enum BallTeamEnum {
LAKERS("洛杉矶湖人"), OKC("雷霆"), TOWN("勇士"), CAVS("骑士");
private String description;
private BallTeamEnum(String description) {
this.description = description;
}
public String getDesc() {
return "BallTeamEnum:" + "name:" + name() + " " + description;
}
public static void main(String[] args) {
for (BallTeamEnum ball : BallTeamEnum.values()) {
System.out.println(ball.getDesc());
}
}
}
2、总结
①枚举类构造方法:每个枚举类都能够调用name(),toString()方法得到自身的描述(返回枚举类的实例名字)。可以提供一个构造器返回额外的信息;
②如果要自定义方法,枚举类的最后一个实例要用“;”分号结束。同时,必须要在定义枚举类的属性和方法之前,先定义枚举类的实例,否则编译器会报错;
③枚举中的方法和构造方法和普通类没有区别,除了有一些限制之外,enum就是一个普通的类。
三、枚举中的switch语句
1、代码示例
package net.oschina.tkj.chapter19.enumclass;
import static net.oschina.tkj.chapter19.enumclass.BallTeamEnum.OKC;
/**
* switch在枚举类中的使用
*
* @author Freedom
*
*/
public class SwitchEnum {
private BallTeamEnum team = OKC;
public void change() {
switch (team) {
case LAKERS:
team = BallTeamEnum.CAVS;
break;
case OKC:
team = BallTeamEnum.TOWN;
break;
case TOWN:
team = BallTeamEnum.LAKERS;
break;
case CAVS:
team = BallTeamEnum.OKC;
break;
}
System.out.println("Team:" + team.getDesc());
}
public static void main(String[] args) {
SwitchEnum switchE = new SwitchEnum();
for (int i = 0; i < 5; i++) {
switchE.change();
}
}
}
2、总结
一般来说,JAVA SE5 switch语句只能使用数值,而枚举本身就具备次序,可以通过ordinal方法获取到其次序,因此可以在枚举类中使用switch。
四、枚举中的values方法
1、代码示例
package net.oschina.tkj.chapter19.valuesmethod;
/**
* 枚举类中的values方法
*
* @author Freedom
*
*/
public enum Explore {
SOUTH, NORTH
}
package net.oschina.tkj.chapter19.valuesmethod;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.HashSet;
import java.util.Set;
/**
* 利用反射机制了解枚举类中的values方法
*
* @author Freedom
*
*/
public class Reflection {
public static Set<String> analyze(Class<?> enumClass) {
System.out.println("analyze start..." + enumClass);
System.out.println("Interface:");
for (Type t : enumClass.getGenericInterfaces()) {
System.out.println(t);
}
System.out.println("parent class:" + enumClass.getSuperclass());
Set<String> set = new HashSet<>();
for (Method m : enumClass.getMethods()) {
set.add(m.getName());
}
System.out.println(set);
System.out.println("analyze enum end...============");
System.out.println();
return set;
}
public static void main(String[] args) {
Set<String> sonEnum = analyze(Explore.class);
Set<String> parentEnum = analyze(Enum.class);
System.out.println("sonEnum.contains(parentEnum) ?:"
+ sonEnum.containsAll(parentEnum));
sonEnum.removeAll(parentEnum);
System.out.println("sonEnum remove parentEnum:" + sonEnum);
}
}
运行结果:
cmd中运行javap反编译指令结果:
2、总结
① javap运行的enum类中可以看出,枚举类为final类不能被继承同时该类有一个父类为Enum;
②枚举类中的实例都是static final为一个引用类型的常量,所以在定义枚举类实例的时候,符合编程规范的写法是将枚举类的实例定义为大写形式,多个字符用"_"分割;
③values方法为编译器添加的static方法。编译器同时还在子类中(自定义的枚举类)中添加了valueOf方法该方法只有一个参数,而父类Enum中也有valueOf方法为两个参数;
④上述方法
sonEnum.removeAll(parentEnum);
移除之后只剩下[values]方法。原因,这里的set集合值存储了方法的名字,而没有考虑方法的签名;
⑤因为 values方法为编译器添加的方法,所以,向上转型为Enum就不能访问values方法。但是,Class类中提供了getEnumConstants方法,因此,Enum类中没有valuesf方法,可以通过Class中的getEnumConstants()方法获取到Enum的实例。