Как задать общий параметр для перечисления, который реализует интерфейс?
Я не уверен на 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 было перечислением.
Спасибо заранее!
Ответы
Ответ 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.