Подтвердить что ты не робот

Дженерики с использованием Enum в Java

У меня есть перечисление

public enum Days {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY 

}

Я хочу сделать класс, который может принимать значения типа Days. Поэтому я использовал Java Generics

public class State<T extend Days>

Но есть ошибка

The type parameter T should not be bounded by the final type Days. 
Final types cannot be further extended

Как я могу решить эту проблему?

4b9b3361

Ответ 1

Не используйте ограничение generics. Там нет необходимости. Просто используйте неограниченный тип, например:

public class State<T> {
    public State(T startState) {
        // whatever
    } 
}

И использовать его:

State<Days> dayState = new State<Days>(Days.SUNDAY);

Это простой типизированный класс, который не нуждается в привязке.

Единственная оценка, которая может иметь смысл, связана с enum:

public class State<T extends Enum<T>> {
    public State(T startState) {
        // whatever
    } 
} 

Эта версия требует, чтобы общий параметр был enum. В этой версии приведенный выше пример использования будет компилироваться, но это не будет компилироваться (например):

State<String> dayState = new State<String>("hello");

потому что String не является enum.

Ответ 2

перечисления являются конечными типами, что означает, что вы не можете продлевать их

общий тип хочет класса как параметра, который является Днем или расширенным классом, но расширенный класс невозможен

поэтому единственным возможным параметром является "Дней", и вам не нужен общий, если возможно только одно значение.

Ответ 3

Вы не можете расширять перечисления в java (http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html до конца). Таким образом, невозможно.

-IF вам нужно, чтобы ваш класс работал только с вашим перечислением, вам не нужны дженерики

-if вместо этого вам нужно, чтобы он работал с другими enum (это имеет смысл?) вам не нужно указывать расширение.

Что делает ваш класс State?

Ответ 4

Здесь нужно сделать

public enum Days{..}

public class State { // no generic argument!
  ...
}

Как бы то ни было, вы не можете иметь State<T extends Days>, потому что единственный способ удовлетворить T extends Days - иметь T be Days. Это означает, что для Days будет final.

Поэтому вместо этого вы должны сделать State не общий и использовать Days непосредственно везде, где вы пытались использовать T. Вы не можете объявить public class State<Days>, потому что тогда он попытается рассматривать Days как переменную типа, а не как класс Days, и это не то, что вы хотите.

Ответ 5

Это компилируется для меня под Java 6:

public enum Days {
  SUNDAY, 
  MONDAY, 
  TUESDAY, 
  WEDNESDAY,
  THURSDAY, 
  FRIDAY, 
  SATURDAY
}

public class State<T extends Days> {
  T state;

  public State(T startState) {
    this.state = startState;
  }
}

private void test() {
  State<Days> state = new State<Days> (Days.MONDAY);
}

Однако, если вы хотите, чтобы ваш объект State изменился с одного enum на другой, вам лучше было бы использовать что-то вроде:

public class State<S extends Enum<S>> {
  final ArrayList<S> states = new ArrayList<S>();
  private S state;

  public State(S startState) {
    states.addAll(EnumSet.allOf(startState.getClass()));
    this.state = startState;
  }

  public S next() {
    return state = states.get((state.ordinal() + 1) % states.size());
  }

  public S prev() {
    return state = states.get((state.ordinal() - 1 + states.size()) % states.size());
  }

  public S set(S newState) {
    return state = newState;
  }

  public S get() {
    return state;
  }
}

private void test() {
  State<Days> state = new State<Days> (Days.MONDAY);
  // ...
}