与仅使用字符串相比,在 FSM 中使用枚举是否有好处?

Is there a benefit to using an enum in a FSM over just using a string?

我想创建一个有限状态机,我能找到的大部分示例代码都使用枚举,我只是想知道它是否比仅使用字符串或 int 来存储状态更有优势。

枚举:

class交通灯{ 枚举状态{ 红、黄、绿 };

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 class 主 {

public static void main(final String[] args) throws InterruptedException {

    final TrafficLight a = new TrafficLight();
    while (true) {
        a.iterate();
    }
}

}

带字符串

public class 交通灯 {

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方法)

它们对我来说似乎完全一样我只是想知道是否存在枚举更好或字符串不起作用的情况。

谢谢。

Enum 相对于 String 的主要优势:这是更具体的类型,因为 Enum 指定了可能的值。
这使您的代码更健壮,也更好地记录。
对于 FSM 和更一般的有界值,这就是您要找的东西。
但是对于 problems/domains 可能的值是在运行时定义的,而不是在编译时定义的(从数据库或其他任何地方检索),Enum 不是最佳选择。

您案例中枚举兴趣的示例

使用 Enum,它不会编译,因为 REDD 未在 State 枚举中声明 class:

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;

枚举值是枚举的实例class,具有自己的实例字段值,但也具有覆盖实例方法的能力

这是枚举在 FSM 或任何域中的另一个优势,其中枚举值与特定 properties/processings 相关联,并且根据枚举值,字段值或方法行为可能不同。

例如,这里我们指定获取下一个转换的行为:

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();
}