【问题标题】:switch statement for a joint of different enum classes in JavaJava中不同枚举类联合的switch语句
【发布时间】:2012-12-19 18:29:14
【问题描述】:

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

【问题讨论】:

  • 你看过任何 Enum 文档吗?
  • 即使有可能,这两个枚举也不会相互关联。您不能针对 case FOUR 或 FIVE 值测试 Enum1。所以你的代码以这种方式编写没有意义。
  • @Heisenbug,嗯,我知道。我不会在真正的项目中这样做,我只是在尝试这种语言。因为所有的枚举类型都是从 java.lang.Enum 隐式派生的,所以我认为不同的枚举类型之间应该有一些通用的关系,我试过了。所以在 JDK7 中,有一种方法可以做到这一点——打开 arg.name() 并在 case 语句中引用所有内容(name() 得到一个字符串,该字符串准确地表示它在其枚举声明中声明的内容)——当然是一些琐碎的发现,但只是为了好玩!
  • @shuangwhywhy:我的评论无意批评,抱歉。我只是指出这一点。总是很高兴看到人们尝试使用这种语言;)

标签: java enums switch-statement


【解决方案1】:

你不能做你正在尝试的事情。一方面,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();
    }
}

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 是的,我知道。我不会在真正的项目中这样做,我只是在尝试这种语言。因为所有的枚举类型都是从 java.lang.Enum 隐式派生的,所以我认为不同的枚举类型之间应该有一些通用的关系,我试过了。所以在 JDK7 中,有一种方法可以做到这一点——打开 arg.name() 并在 case 语句中引用所有内容(name() 得到一个字符串,该字符串准确地表示它在其枚举声明中声明的内容)——当然是一些琐碎的发现,但只是为了好玩!
    【解决方案3】:

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

    我有一个(很奇怪的)替换:创建一个“帮助枚举”,其中包含所有列出的值,并有一个 Map&lt;Request&lt;Enum&lt;?&gt;, HelperEnum&gt;,如下所示:

    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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-27
      • 1970-01-01
      • 2021-01-17
      • 1970-01-01
      • 2017-12-13
      相关资源
      最近更新 更多