我想创建一个有限状态机,我可以找到的大多数示例代码都使用了枚举,而我只是想知道它是否比仅使用字符串或int存储状态更具优势。
带有枚举:
TrafficLight类{ 枚举状态{ 红,黄,绿 };
State state = State.GREEN;
public void iterate() throws InterruptedException {
switch (this.state) {
case RED:
System.out.println("RED");
Thread.sleep(1000);
this.state = State.GREEN;
break;
case GREEN:
System.out.println("GREEN");
Thread.sleep(1000);
this.state = State.YELLOW;
break;
case YELLOW:
System.out.println("YELLOW");
Thread.sleep(1000);
this.state = State.RED;
break;
}
}
公共类主要{
public static void main(final String[] args) throws InterruptedException {
final TrafficLight a = new TrafficLight();
while (true) {
a.iterate();
}
}
}
带有字符串
公共类TrafficLight {
String state = "GREEN";
public void iterate() throws InterruptedException {
switch (state) {
case "RED":
System.out.println("RED");
Thread.sleep(1000);
state = "GREEN";
break;
case "GREEN":
System.out.println("GREEN");
Thread.sleep(1000);
state = "YELLOW";
break;
case "YELLOW":
System.out.println("YELLOW");
Thread.sleep(1000);
state = "RED";
break;
}
}
}
(两者使用相同的main方法)
在我看来,它们似乎都是完全相同的,我只是想知道是否在某些情况下枚举更好,或者字符串不起作用。
谢谢。
答案 0 :(得分:3)
与Enum
相比,String
的主要优势是:Enum
指定了可能的值,因此更具体地键入此类型。
这样可以使您的代码更健壮,也可以更好地记录。
对于FSM和更一般的有界值,这就是您要寻找的。
但是,对于在运行时而不是在编译时(从数据库等中检索)定义可能值的问题/领域,Enum
不是最佳选择。
您的案件中列举枚举的示例
使用Enum时,它将不会编译,因为REDD
枚举类中未声明State
:
case REDD:
System.out.println("RED");
Thread.sleep(1000);
this.state = State.GREEN;
break;
但是使用String时,它将编译并且无法按预期工作:
case "REDD":
System.out.println("RED");
Thread.sleep(1000);
state = "GREEN";
break;
枚举值是枚举类的实例,具有自己的实例字段值,但也具有实例方法的覆盖能力
这是FSM或任何域中枚举的另一个优点,其中枚举值与特定的属性/处理相关联,并且根据枚举值,字段值或方法行为可能有所不同。
例如,在这里我们指定行为以获取下一个过渡:
enum State {
YELLOW(){
@Override
public State next() {
return RED;
}
},
RED(){
@Override
public State next() {
return GREEN;
}
},
GREEN(){
@Override
public State next() {
return YELLOW;
}
};
public abstract State next();
}
现在,枚举拥有足够的逻辑以使不再需要switch
语句:
public void iterate() throws InterruptedException {
System.out.println(state);
Thread.sleep(1000);
state = state.next();
}
答案 1 :(得分:1)
枚举相对于String或Integer / int具有明显的优势,因为它可以保存有关FSM中使用的状态的其他信息。考虑对包含用户界面显示值的状态枚举进行以下扩展:
public enum State {
RED("My Red"),
YELLOW("My Yellow"),
GREEN("My Green");
private String uiValue;
private State(String uiValue) {
this.uiValue = uiValue;
}
public String getUiValue() {
return uiValue;
}
}
使用String或int表示您必须使用“ Magic”值来表示您的状态。相比之下,枚举是描述状态的一种优雅方式-枚举是在单个上下文中的一组值,与比较字符串相比,比较枚举更简单,更优雅。