Java Enum作为Enum中的泛型类型

时间:2013-09-11 09:59:18

标签: java generics methods enums

我试图在抽象类中创建一个抽象方法,它以我自己的Enum作为参数。但我也希望Enum是通用的。

所以我这样说:

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

在实施过程中,我已经知道了那个:

public enum PerspectiveCommands {
    PERSPECTIVE
}

并且方法声明变为:

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

}

但如果我这样做:

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

我无法访问PerspectiveCommands.PERSPECTIVE并出现错误:

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

我已经做了这样的解决方法:

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

但我想知道是否有可能不通过我的解决方法?

3 个答案:

答案 0 :(得分:27)

在您的方法实现中,PerspectiveCommands不是枚举,而是您的类型参数,通常称为T。因此它像axtavt已经说过的那样隐藏了同名的枚举,因此PERSPECTIVE在这里是未知的。

您的抽象方法声明很好,但您可能会使用稍微不同的方法。

public void test(PerspectiveCommands command)不起作用,因为此方法不会覆盖通用版本。原因是通用版本的类型是从参数中推断出来的,因此你可以传递任何枚举。

但是,我假设您有一个定义抽象方法的接口或抽象类。所以尝试这样的事情:

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

答案 1 :(得分:7)

@迈克的回答是要走的路。

public interface Command1 {
}

public enum MyCommand1 implements Command1 {
}

abstract <E extends Enum<E> & Command1> void execute(E command);

这是另一个版本

// intending to be used only on enums
public interface Command2<E extends Enum<E>> extends Command1 {
}

public enum MyCommand2 implements Command2<MyCommand2> {
}

abstract <E extends Enum<E> & Command2<E>> execute(E command);

答案 2 :(得分:6)

正如@axtavt已经指出的那样,问题就是影子。

如果希望代码按原样运行,可以更改类型变量的名称以删除阴影。

public <C extends Enum<C>> void test(Enum<C> command)

我还要为类型边界添加一个接口,只允许命令枚举,而不是每个枚举派生类的实例。

public <C extends Enum<C> & CommandInterface> void test(Enum<C> command)