Я'не уверен на 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
-типа внутри MyWidget
. Проблема, конечно, в том, что "<T extends Enum<T> extends MyInterface>
" не является правильным синтаксисом. Есть ли какой-нибудь способ сделать это?
Я не хочу просто иметь MyWidget<T extends MyInterface>
, потому что важно, чтобы T было перечислением.
Заранее спасибо!
Вместо этого используйте '&
':
public class MyWidget<T extends Enum<T> & MyInterface> {
...
}
В JLS это называется "тип пересечения", но я не могу найти упоминания о нем в учебниках по Java. Я просто скажу, что он делает именно то, что вы хотели, чтобы делало "extends
".
Также, я должен упомянуть, что вы можете иметь столько типов, сколько хотите в типе пересечения. Так что, если вы хотите, вы можете сделать:
public class MyWidget<T extends Enum<T> & MyInterface & Serializable & Cloneable> {
...
}
[Примечание: этот пример кода не следует рассматривать как одобрение интерфейса Cloneable
; он просто был удобен в то время].
В JSR 203 (новый новый IO) для JDK 7 широко используются перечисления, реализующие интерфейсы (например: http://openjdk.java.net/projects/nio/javadoc/java/nio/file/FileVisitOption.html), что позволяет им в будущем иметь определенную свободу маневра для будущих дополнительных наборов опций перечислений. Так что это вполне осуществимый подход, и очевидно, что он был выбран после долгих размышлений в одном большом проекте Sun.