0

I am developing a Java program, where I have to use the following TypeSafeEnum (that is given in an external component):

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

My task-process class has the following method:

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

The compiler fails on the switch statement's line with the following message:

Cannot switch on a value of type MyInterfaceTypeEnum. Only convertible int values, strings or enum variables are permitted.

I googled, but everywhere was written: this TypeSafeEnum pattern may okay. Please give me ideas how to work around this.

UPDATED:

Important to mention: the implementation of MyInterfaceTypeEnum can't be changed by me (it is part of a used (imported) component). Therefore I am forced to use it. So, basic situation is: the "enum" (misused class) is already given.

If I would give up using MyInterfaceTypeEnum, I also would not be able to use a lot of functions (those using this type-safe-enum intensively). So I have no other choice but to accept this and try to find the simpliest possibility.

I know, if-else statement-tree can be used. But I want to avoid that. Since the MyInterfaceTypeEnum was added in an external component (implemented by others and I can't change it).

  • 1
    switch-case only works for actual Java enums. You are stuck with using massive if-else. – Jai Jun 07 '18 at 10:03
  • This are not java enums. – Herr Derb Jun 07 '18 at 10:04
  • @Herr Derb: what does "java enums" mean in this context? –  Jun 07 '18 at 10:05
  • @A.V. it means `enum` keyworded enums. – Ben Jun 07 '18 at 10:06
  • You are currently missuse classes for enum use. This is absolutely not to recommend. Use the java enum type for this and you will have no problems using switch case. Example for java enums https://www.mkyong.com/java/java-enum-example/ – Herr Derb Jun 07 '18 at 10:09
  • Why don't you use a simple `enum`? Was introduced in 1.5 – Robert Kock Jun 07 '18 at 10:11
  • @GhostCat : my comments were gone. But I already answered to Herr Derb; that an external component has this implementation. I can't change it. Otherwise I would have been using normal enums. –  Jun 07 '18 at 10:11
  • Everyone: please check the UPDATE comment at the end of my question. There is written: this class is given, I cant change it. –  Jun 07 '18 at 10:12
  • @GhostCat: my question is no duplicate. Because here is the basic problem that I am forced to use this. Even if I know "normal" enums would be the best choice. Therefore I ask You to please remove the "duplicate" mark. Thank you. –  Jun 07 '18 at 10:14
  • @GhostCat I try to work around the problem, not force Java to work differently. I know that implementation is not good. But as I mentioned more times, I have no choice but using it, even if I personally also dislike. However: you managed to avoid my request to remove the duplicate mark. Since in my question this is about how to work around such a problem like this. Not how to use standard Java-enums. Please... –  Jun 07 '18 at 10:48
  • If you have access to the TypeSafeEnum's fields, you could switch over these - they are String or Integer. – juwil Jun 07 '18 at 11:19
  • @juwil: Can you please give me an example? As answer with code (not here as comment). –  Jun 07 '18 at 11:54

3 Answers3

1

Since java 1.5 Enums are supported in Java

public enum Protocols {
   TCP,
   UDP,
   PCX
}

....
void processInterface(Protocols proto) {

  switch(proto) {
     case TCP: ...
     case UDP: ...
  }
} 
Mark Bramnik
  • 39,963
  • 4
  • 57
  • 97
0

There is no work around. Plain and simple.

The built-in switch statement only works with int, String or (built-in) enum values. Exactly as that error message is telling you. Therefore you are left with if/else chains, or maybe a cascade of if statements, with a return statement in each if block.

Or, you create a true Java enum that wraps around that existing broken enum class of yours. In other words: you create an extra layer of protection, so that all the code you will create isn't impacted by that enum class which you are forced to use. There is even a name for that: anti corruption layer.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
0

Provided you have a field name or a field value in TypeSafeEnum with public access getter, which do store the values of the constructor TypeSafeEnum (String paramString, int paramInt), you could:

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

or do similar with the getter for value (which would be less readable.). @GhostCat's approach of wrapping your class into a real enum looks better to me.

juwil
  • 422
  • 3
  • 9
  • An alternative I didn't think of. To make a bit more useful, the string cases should be using constants. Otherwise the client code starts duplicating these strings all over the place. In other words : that bad code starts creating more bad code. – GhostCat Jun 08 '18 at 10:00