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

Я'не уверен на 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 {
    ...
}

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

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

public class MyWidget {
    ...
}

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

Комментарии (7)

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

Комментарии (2)