@liayun
2016-06-24T07:32:19.000000Z
字数 3258
阅读 1726
java基础加强
一些方法在运行时,它需要的数据不能是任意的,而必须是一定范围内的值,此类问题在JDK5以前采用自定义带有枚举功能的类解决,JDK5以后可以直接使用枚举予以解决。JDK5新增的enum关键字用于定义一个枚举类。
问题:要定义星期几或性别的变量,该怎么定义?假设用1-7分别表示星期一到星期日,但有人可能会写成int weekday = 0;或即使使用常量方式也无法阻止意外。
枚举就是要让某个类型的变量的取值只能为若干个固定值中的一个,否则,编译器就会报错。枚举可以让编译器在编译时就可以控制源程序中填写的非法值,普通变量的方式在开发阶段无法实现这一目标。
定义一个Weekday的类来模拟枚举功能。
每个元素分别用一个公有的静态成员变量表示
public class WeekDay1 {private WeekDay1() {}public final static WeekDay1 SUN = new WeekDay1();public final static WeekDay1 MON = new WeekDay1();public WeekDay1 nextDay() {if(this == SUN) {return MON;} else {return SUN;}}public String toString() {return this == SUN ? "SUN" : "MON";}}
调用方式:
public class EnumTest {public static void main(String[] args) {WeekDay1 weekDay = WeekDay1.MON;System.out.println(weekDay.nextDay()); // SUN}}
枚举可以有若干公有方法或抽象方法。采用抽象方法定义nextDay就将大量的if else语句转移成了一个个独立的类:
public abstract class WeekDay1 {private WeekDay1() {}public final static WeekDay1 SUN = new WeekDay1() {@Overridepublic WeekDay1 nextDay() {return MON;}};public final static WeekDay1 MON = new WeekDay1() {@Overridepublic WeekDay1 nextDay() {return SUN;}};public abstract WeekDay1 nextDay();public String toString() {return this == SUN ? "SUN" : "MON";}}
如果想在一个类中编写完各个枚举类和测试调用类,那么可以将枚举类定义成调用类的内部类。
定义一个Weekday的枚举
public enum WeekDay {SUN,MON,TUE,WED,THI,FRI,SAT; // 分号可有可无}
枚举中的方法介绍
Java中声明的枚举类,均是java.lang.Enum类的孩子,它继承了Enum类的所有方法。
直接打印枚举时,默认就调用了toString()方法。
public class EnumTest {public static void main(String[] args) {WeekDay weekDay2 = WeekDay.FRI;System.out.println(weekDay2);// 默认调用toString()方法}public enum WeekDay {SUN,MON,TUE,WED,THI,FRI,SAT; // 分号可有可无}}
name():表示枚举的名称。
System.out.println(weekDay2.name());
ordinal():表示枚举的排行位置。
System.out.println(weekDay2.ordinal());
枚举的静态方法valueOf():服务器接收的是"MON"字符串,要变成WeekDay.MON对象,就引出了valueOf()方法。在实际开发中,如果客户机提交过来的值不是一个枚举值的话,则转换抛异常。
System.out.println(WeekDay.valueOf("SUN").toString());
枚举的静态方法values():下拉列表框来显示星期几,就引出了values()方法。也即遍历枚举类的所有枚举值。
System.out.println(WeekDay.values().length); // 7
总结:枚举是一种特殊的类,其中的每个元素都是该类的一个实例对象,例如可以调用WeekDay.SUN.getClass().getName和WeekDay.class.getName()。
如果有多个构造方法,如一个带参数的构造方法和一个不带参数的构造方法:
public enum WeekDay {SUN,MON,TUE,WED,THI,FRI,SAT; // 此时必须有分号private WeekDay() {System.out.println("first");}private WeekDay(int day) {System.out.println("second");}}
结论:枚举元素MON和MON()的效果一样,都是调用默认的构造方法。
想选择带参数的构造方法,该如何做呢?
public enum WeekDay {SUN(1),MON(),TUE,WED,THI,FRI,SAT; // 此时必须有分号private WeekDay() {System.out.println("first");}private WeekDay(int day) {System.out.println("second");}}
增加上表示时间的构造方法。
public enum TrafficLamp {RED(30){ // new 子类的实例对象,并调用父类的有参构造方法(RED引用名称去引用)@Overridepublic TrafficLamp nextLamp() {return GREEN;}},GREEN(45){@Overridepublic TrafficLamp nextLamp() {return YELLOW;}},YELLOW(5){@Overridepublic TrafficLamp nextLamp() {return RED;}};public abstract TrafficLamp nextLamp();private int time;private TrafficLamp(int time) {this.time = time;}}
写带有抽象方法的枚举步骤和技巧:
enum TrafficLamp {RED,GREEN,YELLOW}
enum TrafficLamp {RED,GREEN,YELLOW;public abstract TrafficLamp next();}
enum TrafficLamp {RED{},GREEN{},YELLOW{};public abstract TrafficLamp next();}
填充各个{}中的next方法
注意:枚举只有一个成员时,就可以作为一种单例的实现方式。代码如下:
public enum Character { // classA; // Object}