@liayun
2016-06-24T15:32:19.000000Z
字数 3258
阅读 1510
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() {
@Override
public WeekDay1 nextDay() {
return MON;
}
};
public final static WeekDay1 MON = new WeekDay1() {
@Override
public 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引用名称去引用)
@Override
public TrafficLamp nextLamp() {
return GREEN;
}
},
GREEN(45){
@Override
public TrafficLamp nextLamp() {
return YELLOW;
}
},
YELLOW(5){
@Override
public 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 { // class
A; // Object
}