导言:
在Java中,我们可以通过static final来定义常量。例如,我们希望定义周一到周日这7个常量,可以用7个不同的int表示:
public class Weekday { public static final int SUN = 0; public static final int MON = 1; public static final int TUE = 2; public static final int WED = 3; public static final int THU = 4; public static final int FRI = 5; public static final int SAT = 6; }
使用常量的时候,可以这么引用
if (day == Weekday.SAT || day == Weekday.SUN) { // TODO: work at home }
也可以把常量定义为字符串类型,例如,定义3种颜色的常量:
public class Color { public static final String RED = "r"; public static final String GREEN = "g"; public static final String BLUE = "b"; }
使用常量的时候,可以这么引用:
String color = ... if (Color.RED.equals(color)) { // TODO: }
无论是int常量还是String常量,使用这些常量来表示一组枚举值的时候,有一个严重的问题就是,编译器无法检查每个值的合理性。例如:
if (weekday == 6 || weekday == 7) { if (tasks == Weekday.MON) { // TODO: } }
上述代码编译和运行均不会报错,但存在两个问题:
注意到Weekday定义的常量范围是0~6,并不包含7,编译器无法检查不在枚举中的int值;
定义的常量仍可与其他变量比较,但其用途并非是枚举星期值。enum
Java使用enum定义枚举类型,它被编译器编译为final class Xxx extends Enum { … }; 通过name()获取常量定义的字符串,注意不要使用toString(); 通过ordinal()返回常量定义的顺序(无实质意义); 可以为enum编写构造方法、字段和方法 enum的构造方法要声明为private,字段强烈建议声明为final; enum适合用在switch语句中。
测试代码:
import org.junit.Test; /** * @Describtion Todo * @Author yonyong * @Date 2019/8/12 16:39 * @Version 1.0.0 **/ public class EnumTest { //***********test1******************** enum Weekday { SUN, MON, TUE, WED, THU, FRI, SAT; } @Test public void t (){ //简单的枚举类使用 Weekday day = Weekday.SUN; if (day == Weekday.SAT || day == Weekday.SUN) { System.out.println("Work at home!"); } else { System.out.println("Work at office!"); } } @Test public void t_methods(){ //name()方法 ---返回常量名 String s = Weekday.SUN.name(); // "SUN" //ordinal() ---返回定义的常量的顺序,从0开始计数,例如: int n = Weekday.MON.ordinal(); //1 //注意:如果在代码中编写了类似if(x.ordinal()==1)这样的语句,就要保证enum的枚举顺序不能变。新增的常量必须放在最后。 } //***********test2******************** enum Weekday2 { //注意:枚举类的字段也可以是非final类型,即可以在运行期修改,但是不推荐这样做! MON(1), TUE(2), WED(3), THU(4), FRI(5), SAT(6), SUN(0); public final int dayValue; private Weekday2(int dayValue) { this.dayValue = dayValue; } } //枚举类可以应用在switch语句中。因为枚举类天生具有类型信息和有限个枚举常量,所以比int、String类型更适合用在switch语句中: @Test public void t2 (){ //枚举类赋值 Weekday2 day = Weekday2.SUN; if (day.dayValue == 6 || day.dayValue == 0) { System.out.println("Work at home!"); } else { System.out.println("Work at office!"); } } //***********test3******************** enum Weekday3 { //进一步理解枚举类赋值,以及toString方法的重写 MON(1, "星期一"), TUE(2, "星期二"), WED(3, "星期三"), THU(4, "星期四"), FRI(5, "星期五"), SAT(6, "星期六"), SUN(0, "星期日"); public final int dayValue; private final String chinese; private Weekday3(int dayValue, String chinese) { this.dayValue = dayValue; this.chinese = chinese; } @Override public String toString() { return this.chinese; } } @Test public void t3 (){ Weekday3 day = Weekday3.SUN; if (day.dayValue == 6 || day.dayValue == 0) { System.out.println("Today is " + day + ". Work at home!"); } else { System.out.println("Today is " + day + ". Work at office!"); } } @Test public void t3_switch (){ //枚举类用于switch Weekday day = Weekday.MON; switch(day) { case MON: case TUE: case WED: case THU: case FRI: System.out.println("Today is " + day + ". Work at office!"); break; case SAT: case SUN: System.out.println("Today is " + day + ". Work at home!"); break; default: //加上default语句,可以在漏写某个枚举常量时自动报错,从而及时发现错误。 throw new RuntimeException("cannot process " + day); } } }