Garcia Julien Garcia Julien - 5 months ago 7
Java Question

Java Enum as generic type in Enum

i'm trying to create an abstract method in a abstract class that takes my own Enum as argument. But I want also that that enum will be generic.

So i declared it like that:

public abstract <T extends Enum<T>> void test(Enum<T> command);


In the implementation, I have en enum as that one:

public enum PerspectiveCommands {
PERSPECTIVE
}


and the method declaration become:

@Override
public <PerspectiveCommands extends Enum<PerspectiveCommands>> void test(Enum<PerspectiveCommands> command) {

}


But if I do:

@Override
public <PerspectiveCommands extends Enum<PerspectiveCommands>> void test(Enum<PerspectiveCommands> command) {
if(command == PerspectiveCommands.PERSPECTIVE){
//do something
}
}


I don't have access to the PerspectiveCommands.PERSPECTIVE with the error:


cannot find symbol symbol: variable PERSPECTIVE location: class
Enum where PerspectiveCommands is a
type-variable:
PerspectiveCommands extends Enum declared in method test(Enum)


I made a workaround like that:

public <T extends Enum<T>> byte[] executeCommand(Enum<T> command) throws Exception{
return executeCommand(command.name());
}

@Override
protected byte[] executeCommand(String e) throws Exception{
switch(PerspectiveCommands.valueOf(e)){
case PERSPECTIVE:
return executeCommand(getPerspectiveCommandArray());
default:
return null;
}
}


But I would like to know if its possible to not pass by my workaround?

Thanks in advance

Answer

In your method implementation PerspectiveCommands is not the enum but your type parameter, which often is called T. It thus shadows the enum of the same name like axtavt already said, thus PERSPECTIVE is unknown here.

Your abstract method declaration is fine but you might use a slightly different approach.

public void test(PerspectiveCommands command) would not work, since this method would not override the generic version. The reason is that with the generic version the type is inferred from the parameter and thus you could pass any enum.

However, I assume you have an interface or abstract class which defines the abstract method. So try something like this:

interface TestInterface<T extends Enum<T>>
{
  public abstract void test(T command);
}

class TestImpl implements TestInterface<PerspectiveCommands>
{
  @Override
  public void test(PerspectiveCommands command) {
    if(command == PerspectiveCommands.PERSPECTIVE){
        //do something
    }
  }
}