导言:
在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);
}
}
}