一、为什么要有枚举
问题:要定义星期几或性别的变量,该怎么定义?
假设用1-7分别表示星期一到星期日,但有人可能会写成int weekday = 0;
或即使使用常量方式也无法阻止意外。
枚举就是要让某个类型的变量的取值只能为若干个固定值中的一个,否则,编译器就会报错。
枚举可以让编译器在编译时就可以控制源程序中填写的非法值,普通变量的方式在开发阶段无法实现这一目标。
用普通类如何实现枚举功能,定义一个Weekday的类来模拟枚举功能。
私有的构造方法
每个元素分别用一个公有的静态成员变量表示
可以有若干公有方法或抽象方法。采用抽象方法定义nextDay就将大量的if.else语句转移成了一个个独立的类。
二、枚举的基本应用
举例:定义一个Weekday的枚举。扩展:枚举类的values,valueOf,name,toString,ordinal等方法总结:枚举是一种特殊的类,其中的每个元素都是该类的一个实例对象,例如可以调用WeekDay.SUN.getClass().getName和WeekDay.class.getName()得到的是同一个类的名字。
public class EnumTest {
public static void main(String[] args) {
WeekDay wk1 = WeekDay.SUN;/**@addition 相关知识推介Java的每个类都带有一个运行时类对象,该Class对象中保存了创建对象所需的所有信息。可以用.class返回此 Object 的运行时类Class对象,也可以用getClass()获得。获得此对象后可以利用此Class对象的一些反射特性进行操作,例如:this.getClass().newInstance(); //用缺省构造函数创建一个该类的对象this.getClass().getInterfaces(); //获得此类实现的接口信息this.getClass().getMethods();//获得此类实现的所有公有方法this.getClass().getName();//获得此类的名称*///输出wk1的类名,事实证明每个Enum的属性都是一个Enum类System.out.println(wk1.getClass().getName());//com.niechi.enhance.day01.EnumTest$WeekDay//检验运行时的类对象与创建这个对象的类是否是同一个类型,由于使用的WeekDay.class.getClass()获取该类的类,可以说是父类System.out.println(wk1.getClass().getName() == WeekDay.class.getClass().getName());//输出结果为false,/*Class与class都继承自Object,class实体来代表java运行时的class和interface等等,Class.class就是得到或者生成这个Class类的Class Object;而.getClass()本就是返回一个类对应的Class Object ,所以Class.class.getClass()最后还是返回Class Object*///Class.class.getClass();System.out.println(Class.class.getClass().getName());//java.lang.Class//对WeekDay.class 进行getClass()操作与对Class.class进行getClass()操作的结果是相同System.out.println(WeekDay.class.getClass().getName());//java.lang.Class//比较对内存实体class进行getClass之后是否相等System.out.println(Class.class.getClass()==WeekDay.class.getClass());//true//比较WeekDay.FRI与WeekDay.class 是否是相同的对象System.out.println(WeekDay.FRI.getClass().getName()==WeekDay.class.getName());//true//Enum.class.getClass()同样也是ClassSystem.out.println(Enum.class.getClass().getName());//java.lang.ClassString enumName = Enum.class.getName();}System.out.println(enumName);//java.lang.Enum//注意在定义的时候,enum开头字母为小写,如果是大写会报错,而且很难找到错误原因//但是在导入包的是确是大写的Enum,这一点也需要格外注意, 这里其实也根本不需要导入包public enum WeekDay{//如果不小心将定义枚举的关键词,大写之后,会报这个错误:Syntax error, insert ";" to complete FieldDeclaration,大概的意思是:通过在语句后面添加分号,来完成完成字段声明MON,TUE,WEN,THU,FRI,STA,SUN;
}
}
四、注意事项
所有自行编写的 枚举类 都默认自动继承 java.lang.Enum<E extends Enum<E>> 。
其中 java.lang.Enum 类的 toString() 方法说明:返回枚举常量的名称,它包含在声明中。
这意味着你自行编写的 枚举类 都默认继承这个 toString 方法的逻辑。
五、枚举的高级运用
枚举就相当于一个类,其中也可以定义构造方法、成员变量、普通方法和抽象方法。枚举元素必须位于枚举体中的最开始部分,枚举元素列表的后要有分号与其他成员分隔。把枚举中的成员方法或变量等放在枚举元素的前面,编译器报告错误。带构造方法的枚举
构造方法必须定义成私有的如果有多个构造方法,该如何选择哪个构造方法?枚举元素MON和MON()的效果一样,都是调用默认的构造方法。
带方法的枚举
定义枚举TrafficLamp实现普通的next方法实现抽象的next方法:每个元素分别是由枚举类的子类来生成的实例对象,这些子类采用类似内部类的方式进行定义。增加上表示时间的构造方法枚举只有一个成员时,就可以作为一种单例的实现方式。