Switch statement for connecting different enum classes in Java

I have two enum classes, for example Enum1 and Enum2:

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

, and I have a method like this:

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

So, is it possible to switch the value of a generic enumeration type?


There is one way to change it to strings (only works in 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 } } 
+2
source share
3 answers

You cannot do what you are trying. First, the enum switch is actually a shorthand for switching to ordinal() enumeration. Therefore, even if you can force the switch to recognize its type of "joint enumeration", the operator has duplicate case branches. (For example, ONE and FOUR both have serial number 0.)

One approach may be to move the action to the enumerations themselves. Then you can use each type of enum type for a common interface:

 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() { . . . } } } 

Then you can implement your method to simply delegate the processing to the actor:

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

You will need to point the enumeration to a specific type before the switch statement (and therefore have a separate switch statement for each type). That said this is not the best of ideas. You will probably find a better solution, refactoring the code, so you do not need to do this.

+2
source

The switch you specified is clearly not working.

I have a (rather strange) substitution: create a "helper enumeration" that contains all the listed values ​​and has Map<Request<Enum<?>, HelperEnum> , for example:

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

(unverified!)

So you can do

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

(a similar version was first published here )

It would be useful to have a common interface implemented by the enumerations listed, but this one will probably work too.

0
source

Source: https://habr.com/ru/post/1263435/


All Articles