Java枚举变量
此秘笈需要对类和方法的使用有基本了解。
github地址: https://github.com/Java-A-2019/JavaEnum/tree/master
使用场景
1. 有很多种类的情况,但是简单地用1,2,3数字表达,又没有办法满足需要。比方说,我们约定1为空地,2为墙壁,一旦数量多起来,大家就会非常难受。因为大家记不住,不如用Land和Wall表示,这样有语义,大家就容易记住和使用。另外,假如用户输入-1等非法值,也会导致你非常头痛。
2. Java的枚举类型在C的基础之上结合了类的特性,功能更加强大!枚举类型可以拥有自己的方法和属性!
3. 注意,枚举变量虽然好用,但是也不能乱用!有的时候,需要仔细考虑,到底使用多个子类比较好,还是用多个枚举变量比较好。枚举变量一般就存储几个关键信息就好了,并且在必要的时候做一些parse的工作。如果你需要给枚举变量增加更多的function,那么这个使用你最好用子类来操作而不是枚举变量。
简单用法
创建
public enum EntityType {
LAND, WALL, GREEN_SLIME, RED_SLIME, SKELETON_MAN
}
使用
public class TestEntityType {
public static void main(String[] args) {
EntityType type = EntityType.GREEN_SLIME;
switch (type) {
case LAND:
System.out.println("LAND");
break;
case WALL:
System.out.println("WALL");
break;
case GREEN_SLIME:
System.out.println("GREEN_SLIME");
break;
default:
System.out.println("Illegal");
}
}
}
中阶用法
当然,童鞋们肯定不会满足于普通用法。接下来的用法,会给枚举变量添加属性。
下面这个例子创建周一到周日七个枚举变量,每个枚举变量中存储着他们的打印信息。下面存储的是一个String值,你可以同时存储多个不同类型的值。
public enum DayType {
SUN("Sun"), MON("Mon"), TUES("Tues"), WEDN("Wed"),
THUR("Thur"), FRI("Fri"), SAT("Sat");
private final String printMark;
DayType(String printMark) {
this.printMark = printMark;
}
public String getPrintMark() {
return printMark;
}
}
对枚举变量的遍历
public class TestDayType {
public static void main(String[] args) {
DayType[] typeValues = DayType.values();
for (int i = 0 ; i < typeValues.length; i++)
System.out.println(typeValues[i].getPrintMark());
}
}
再举一个简单的例子,用于上下左右命令的转化。
public enum Direction {
UP(1, "向上"), DOWN(2, "向下"), LEFT(3, "向左"), RIGHT(4, "向右");
private final int id; // 仅仅是为了做示范添加的
private final String cnName;
Direction(int id, String cnName){
this.id = id;
this.cnName =cnName;
}
public static Direction parseDirection(String direction) {
switch (direction) {
case "w":
return UP;
case "s":
return DOWN;
case "a":
return LEFT;
case "d":
return RIGHT;
}
return null;
}
public String getCnName() {
return cnName;
}
}
相关测试如下
public class TestDirection {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);// new Scanner不能放在循环中,
// 否则会非常消耗资源。
while (true) {
String command = input.nextLine();
if (command.equals("exit")) break; // 退出程序
Direction dir = Direction.parseDirection(command);
if (dir == null) System.out.println("Illegal command!");
else System.out.println(dir.getCnName());
}
}
}
结合反射机制
接下来地这个例子,就非常复杂了,需要对抽象类和反射机制有所了解。请自行下载demo。
public enum MonsterType {
NULL(null), BAT(Bat.class), BOSS(Boss.class), SLIME(Slime.class);
private final Class clz;
MonsterType(Class clz) {
this.clz = clz;
}
public Monster getInstance(){
if (this.clz == null) return null;
Monster monster = null;
try {
monster = (Monster) this.clz.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
return monster;
}
}
相关测试
public class TestMonster {
public static void main(String[] args) {
MonsterType[] types = MonsterType.values();
for (int i = 0 ; i < types.length; i++) {
Monster monster = types[i].getInstance();
if (monster != null) monster.attack();
}
}
}
更高级的做法
如果想要让你的代码更加简单,可以考虑使用HashMap。在这里就不再赘述了。