2

我有两个枚举类,比如 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
    }
}
4

3 回答 3

5

你不能做你正在尝试的事情。一方面,enum开关实际上是ordinal()枚举中开关的简写。因此,即使您可以让开关识别您的“联合枚举”类型,该语句也有重复的case分支。(例如,ONE两者FOUR都有序数 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();
    }
}
于 2012-12-19T18:50:15.427 回答
2

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

于 2012-12-19T18:35:59.903 回答
0

你提到的开关显然不起作用。

我有一个(非常奇怪的)替换:创建一个“帮助枚举”,其中包含列出的所有值,并有一个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: ....
}

(模拟版本首次在这里发布)

有一个由所讨论的枚举实现的通用接口会很有帮助,但这个接口可能也可以工作。

于 2017-01-27T09:54:44.300 回答