Обобщения с использованием Enum в Java - PullRequest
13 голосов
/ 13 февраля 2012

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

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

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

Ответы [ 5 ]

9 голосов
/ 13 февраля 2012

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

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

таким образом, единственный возможный параметр - это Days, и вам не нужно универсальное значение, если возможно только одно значение

7 голосов
/ 13 февраля 2012

Не используйте родовые связи.Не нужно.Просто используйте неограниченный тип, например:

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.

5 голосов
/ 13 февраля 2012

Что нужно сделать здесь:

public enum Days{..}

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

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

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

5 голосов
/ 13 февраля 2012

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

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

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

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

2 голосов
/ 13 февраля 2012

Это нормально для меня под 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);
  // ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...