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

Как задать общий параметр для перечисления, который реализует интерфейс?

Я не уверен на 100%, что это хорошая идея, но сегодня я столкнулся с некоторым кодом, который в настоящее время реализован как:

class MyWidget <T extends Enum<T> > {
  MyWidget(Map<T, Integer> valueMap) {
    mValueMap = valueMap;
  }

  Map<T, Integer> mValueMap;
}

где MyWidget затем предлагает методы, которые используют mValueMap для преобразования переданного Enum в/из Integer.

То, что я рассматривал, было попыткой реорганизовать это, так что я объявляю свое перечисление:

interface MyInterface {
  public Integer getValue();
}

enum MyEnum implements MyInterface {
  foo, bar;
  public Integer getValue() {
    return ordinal();
  }
}

И я мог бы переписать MyWidget во что-то, что выглядело смутно следующим образом:

public class MyWidget<T extends Enum<T> extends MyInterface> {
  ...
}

и затем сможет вызвать метод getValue() из MyInterface в T -type объектов в пределах MyWidget. Проблема, конечно, в том, что "<T extends Enum<T> extends MyInterface>" является недопустимым синтаксисом. Есть ли способ снять это?

Я не хочу просто иметь MyWidget<T extends MyInterface>, потому что также важно, чтобы T было перечислением.

Спасибо заранее!

4b9b3361

Ответ 1

Вместо этого используйте '&':

public class MyWidget<T extends Enum<T> & MyInterface> {
    ...
}

JLS называет это "тип пересечения", но я не могу найти упоминания об этом в учебниках Java. Я просто скажу, что он делает именно то, что вы хотели, чтобы "extends" сделал.

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

public class MyWidget<T extends Enum<T> & MyInterface & Serializable & Cloneable> {
    ...
}

[Примечание: этот образец кода не должен интерпретироваться как подтверждение интерфейса Cloneable; это было просто удобно в то время.]

Ответ 2

JSR 203 (новый новый IO) для JDK 7 много использует перечисления, которые реализуют интерфейсы (например: http://openjdk.java.net/projects/nio/javadoc/java/nio/file/FileVisitOption.html), чтобы позволить им некоторое пространство для маневра в будущем для будущих дополнительных наборов опций перечисления. Таким образом, это осуществимый подход и, очевидно, тот, который был выбран после большого размышления в одном крупном проекте Sun.