Java - 如何使用Type Safe Enumerations作为switch-case语句?

时间:2018-06-07 10:00:25

标签: java enums type-safety

我正在开发一个Java程序,我必须使用以下TypeSafeEnum(在外部组件中给出):

public class MyInterfaceTypeEnum
    extends TypeSafeEnum
{
    public MyInterfaceTypeEnum(String paramString, int paramInt)
    {
        super(paramString, paramInt);
    }

    public static final MyInterfaceTypeEnum UNKNOWN = new MyInterfaceTypeEnum("UNKNOWN", 0);
    public static final MyInterfaceTypeEnum TCP = new MyInterfaceTypeEnum("TCP", 10);
    public static final MyInterfaceTypeEnum UDP = new MyInterfaceTypeEnum("UDP", 20);
    public static final MyInterfaceTypeEnum IPX = new MyInterfaceTypeEnum("IPX", 30);
    public static final MyInterfaceTypeEnum RS232 = new MyInterfaceTypeEnum("RS232", 40);
}

我的任务流程类有以下方法:

private void processInterface(MyInterfaceTypeEnum type)
{
    switch(type)
    {
    case RS232:
        {
            // do action
            break;
        }
    case TCP:
    case UDP:
        {
            // do action
            break;
        }
    case IPX:
        {
            // do action
            break;
        }
    case UNKNOWN:
    default:
        {
            // do default action
            break;
        }
    }
}

编译器在switch语句的行上失败,并显示以下消息:

  

无法打开MyInterfaceTypeEnum类型的值。只有可兑换的int   允许使用值,字符串或枚举变量。

我用谷歌搜索,但到处都写着:这个TypeSafeEnum模式可能没问题。请告诉我如何解决这个问题。

更新:

重要提一下:我无法更改MyInterfaceTypeEnum的实现(它是已使用(导入)组件的一部分)。因此我被迫使用它。所以,基本情况是:已经给出了“枚举”(误用类)。

如果我放弃使用MyInterfaceTypeEnum,我也将无法使用很多功能(那些使用此类型安全枚举的功能)。所以我别无选择,只能接受这一点,并试图找到最简单的可能性。

我知道,if-else可以使用statement-tree。但我想避免这种情况。由于MyInterfaceTypeEnum已添加到外部组件中(由其他人实施,我无法更改)。

3 个答案:

答案 0 :(得分:1)

由于Java支持Java 1.5枚举

public enum Protocols {
   TCP,
   UDP,
   PCX
}

....
void processInterface(Protocols proto) {

  switch(proto) {
     case TCP: ...
     case UDP: ...
  }
} 

答案 1 :(得分:1)

没有解决方法。干净利落。

内置switch语句仅适用于int,String或(内置)枚举值。正如该错误消息告诉您的那样。 因此,您可以使用if / else链,或者if if语句的级联,并在每个if块中使用return语句。

或者,您创建了一个真正的Java枚举,它包含了您现有的已损坏的枚举类。换句话说:您创建了一个额外的保护层,以便您将创建的所有代码不会受到您强制使用的枚举类的影响。甚至有一个名称:反腐败层。

答案 2 :(得分:1)

如果你在TypeSafeEnum中有一个带有公共访问getter的字段名或字段值,它确实存储了构造函数TypeSafeEnum(String paramString,int paramInt)的值,你可以:

private void processInterface(MyInterfaceTypeEnum type){
switch(type.getName()) {
case "RS232":
    {
        // do action
        break;
    }
case "TCP":

或者使用getter做类似的值(可读性较差)。 @ GhostCat将你的课程包装成真正的enum的方法看起来更好。