用于Java中不同枚举类的联合的switch语句

时间:2012-12-19 18:29:15

标签: java enums switch-statement

我有两个枚举类,比如Enum1和Enum2:

enum Enum1 {ONE, TWO, THREE}
enum Enum2 {FOUR, FIVE}

我有这样的方法:

public <E extends Enum<E>> method (E arg) {
    switch (arg) {    // Here is the compile error -- Cannot switch
                      // on a value of type E. Only convertible int
                      // values, strings or enum variables are permitted

                      // (And of course, all the cases are incorrect
                      // because the enum set is unknown)
        case ONE:
            // do something
        case TWO:
            // do something
        case THREE:
            // do something
        case FOUR:
            // do something
        case FIVE:
            // do something
        default:
            // do something
    }
}

那么可以切换泛型枚举类型的值吗?


有一种方法可以将其更改为字符串(仅适用于JDK7):

public <E extends Enum<E>> method (E arg) {
    switch (arg.name()) {
        case "ONE":
            // do something
        case "TWO":
            // do something
        case "THREE":
            // do something
        case "FOUR":
            // do something
        case "FIVE":
            // do something
        default:
            // do something
    }
}

3 个答案:

答案 0 :(得分:5)

你不能做你想做的事。首先,enum开关实际上是在枚举的ordinal()上切换的简写。因此,即使您可以让开关识别您的“联合枚举”类型,该语句也会有重复的case分支。 (例如,ONEFOUR都有序数0。)

一种方法可能是将操作移动到枚举本身。然后,您可以让每个enum类型实现一个公共接口:

interface Actor {
    void doSomething();
}

enum Enum1 implements Actor {
    ONE {
        public void doSomething() { . . . }
    },
    TWO {
        public void doSomething() { . . . }
    },
    THREE {
        public void doSomething() { . . . }
    }
}

enum Enum2 implements Actor {
    FOUR {
        public void doSomething() { . . . }
    },
    FIVE {
        public void doSomething() { . . . }
    }
}

然后你可以实现你的方法来简单地将处理委托给actor:

public void method(Actor actor) {
    if (actor == null) {
         // default action
    } else {
        actor.doSomething();
    }
}

答案 1 :(得分:2)

您需要在switch语句之前将枚举转换为特定类型(因此每种类型都有一个单独的switch语句)。说,这不是最好的想法。您可能会通过重构代码找到更好的解决方案,这样您就不需要这样做了。

答案 2 :(得分:0)

你提到的转换显然不起作用。

我有一个(非常奇怪的)替换:创建一个“helper enum”,其中包含列出的所有值,并且有一个Map<Request<Enum<?>, HelperEnum>,如下所示:

private enum HelperEnum {
       ONE(Enum1.ONE),
       TWO(Enum1.TWO),
       THREE(Enum1.THREE),
       FOUR(Enum2.FOUR),
       FIVE(Enum2.FIVE);

       private Enum<?> source;

       private HelperEnum(Enum<?> source) {
           this.source = source;
       }

       private static Map<Enum<?>, HelperEnum> map;

       public static HelperEnum lookUp(Enum<?> source) {
           if (map == null) {
               map = Arrays.stream(HelperEnum.values())
                   .collect(Collectors.toMap(x -> x.source, x -> x));
           }
           return map.get(source);
       }

(未经测试!)

这样你可以做到

switch(HelperEnum.lookUp(a_request)){
    case ONE: ....
    case TWO: ....
    case THREE: ....
    case FOUR: ....
    case FIVE: ....
}

(类似版本首次发布here

有问题的枚举实现了一个通用接口会有所帮助,但是这个接口可能也会有效。