Java Enum как общий тип в Enum
Я пытаюсь создать абстрактный метод в абстрактном классе, который принимает мой собственный Enum в качестве аргумента. Но я хочу также, чтобы Enum был общим.
Итак, я объявил это так:
public abstract <T extends Enum<T>> void test(Enum<T> command);
В реализации у меня есть en enum как таковой:
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;
}
}
Но я хотел бы знать, возможно ли это пройти мимо моего обходного пути?
Ответы
Ответ 1
В вашем методе реализация PerspectiveCommands
- это не перечисление, а ваш параметр типа, который часто называется T
. Таким образом, он теняет одноименное перечисление, как уже говорилось, так как 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
}
}
}
Ответ 2
@mike ответ - путь.
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);
Ответ 3
Как уже отмечалось, @axtavt, проблема заключается в теневом изображении.
Если вы хотите, чтобы ваш код работал так, как он есть, вы можете изменить имя переменной типа, чтобы удалить затенение.
public <C extends Enum<C>> void test(Enum<C> command)
Я бы также добавил интерфейс к границе типа, чтобы просто разрешить перечисления команд, а не экземпляр каждого класса, произведенного перечислением.
public <C extends Enum<C> & CommandInterface> void test(Enum<C> command)