1.创建一个最简单的枚举类型
创建枚举类型要使用enum关键字,隐含了所创建的类型都是java.lang.Enum类的子类,它是抽象类。其中,枚举类型符合通用模式 Class Enum<E extends Enum<E>>,而 E 表示枚举类型的名称。枚举类型的每一个值都将映射到 protected Enum(String name, int ordinal) 构造函数中,在这里,每个值的名称都被转换成一个字符串,并且序数设置表示了此设置被创建的顺序。
public enum Size{ SMALL, MEDIUM, LARGE;}
实际上调用了三次构造函数:
new Enum<Size>("SMALL",0);new Enum<Size>("MEDIUM",1);new Enum<Size>("LARGE",2);
值的名字和顺序值可以分别通过name()/toString()、ordinal()获得。
自建的枚举类除了继承Enum类的方法外还会自动获得两个方法values()和valueOf(String name)。不需要自己定义就可以直接使用。这其中的原理我不太清楚,麻烦明白的人给我讲讲。
values()可以用来遍历枚举类中的值,valueOf(String name)可以用来通过名字获得具体的枚举值。
获得枚举类值的方法:有三种方式,具体见代码。
public class MostSimpleEnum {public enum Size{ SMALL, MEDIUM, LARGE; }
public static void main(String[] args){ //两种获得枚举类型的方法 Size s1 = Size.SMALL; Size s2 = Enum.valueOf(Size.class, "SMALL"); Size s3 = Size.valueOf("MEDIUM");//1
//直接使用‘=’来比较两个枚举类型是否相等 if(Size.LARGE == Enum.valueOf(Size.class, "LARGE")){ System.out.println("Size.LARGE == Enum.valueOf(Size.class, /"LARGE/")"); }
//结果同上,枚举重载了equals方法,但比较方法同上 System.out.println("Size.MEDIUM.equals(Enum.valueOf(Size.class, /"MEDIUM/")):"+ Size.MEDIUM.equals(Enum.valueOf(Size.class, "MEDIUM")));
//遍历枚举类型中所有的成员 for(Size s:Size.values()){//2 //1.定义的序号 2.定义的名称 3.在Enum中被重载,同name() System.out.println(s.ordinal()+" "+s.name()+" "+s.toString()); }
//分析在抽象类Enum中没有定义的两个方法values()和valuesOf()的来历 analyzeEnum(s1);
//定义的枚举类默认继承的抽象类java.lang.Enum //有两个特殊的方法,我们并没有定义,结果却显示来自我们自定定义的类 //前面都已经使用过的,1.valueOf(String name),2.values() //枚举类自动包括这两个事先被定义好的方法 System.out.println("获得"+s3); }
public static void analyzeEnum(Enum e){ System.out.println("class:"+e.getClass().getName()); System.out.println("declear class:"+e.getClass().getDeclaringClass()); System.out.println("super class:"+e.getClass().getSuperclass().getName()); Class<?>[] interfaces = e.getClass().getInterfaces(); for(Class c:interfaces){ System.out.println("implement interdace:"+c.getName()); }
Method[] methods = e.getClass().getMethods(); for(Method m:methods){ System.out.println("mehtods:"+m.getName()+" from:"+m.getDeclaringClass()); } }}
2.创建一个复杂点的枚举类Week, 在这个枚举类中我们为它添加自己定义的成员、构造器、方法。 注意虽然在Enum中有构造器,但是我们无法在自定义的枚举类中调用它,直接继承java.lang.Enum也是不允许的。我们自己定义的构造器只能被定义成private或者package-protected,同样在我们也无法调用这个自定义的狗构造器。
public enum Week { //定义枚举类的值 Monday("MON","星期一"), Tuesday("TUE","星期二"), Wednesday("WED","星期三"), Thursday("THU","星期四"), Friday("FRI","星期五"), Saturday("SAT","星期六"){ @Override public boolean isRest(){ return true; } }, Sunday("SUN","星期日"){ @Override public boolean isRest(){ return true; } };
private String abbreviation = "";//缩写 private String chineseName = "";//中文名字
//定义自己的构造器
private Week(String abbreviation,String chineseName){ this.abbreviation = abbreviation; this.chineseName = chineseName; }
public String abbreviation(){ return abbreviation; }
public String getChineseName(){ return chineseName; }
//周六和周日应该返回true,此方法在周六和周日的值中被重载
public boolean isRest(){ return false; }
//重载,对它进行稍稍的改动
@Override
public String toString(){ return this.getClass().getName()+"."+this.name(); }}
//测试Week
public class WeekTest { public static void main(String[] args){ for(Week week:Week.values()){ System.out.println("-----------------------------------------"); System.out.println("ordinal():"+week.ordinal()); System.out.println("name():"+week.name()); System.out.println("getChineseName():"+week.getChineseName()); System.out.println("abbreviation():"+week.abbreviation()); System.out.println("isRest():"+week.isRest()); System.out.println("toString():"+week); } }}
顺便说一下,继承或实现接口的方法和一般Java类是相同的。
参考: 驯服 Tiger: 深入研究枚举类型 http://www-128.ibm.com/developerworks/cn/java/j-tiger04195/ Java 1.5新特性Enum的用法 http://conkeyn.javaeye.com/blog/232757