Обобщения Java для типов Enum - PullRequest
0 голосов
/ 02 мая 2011

Я пытаюсь написать класс Java, одна часть которого требует сопоставления значений неизвестного перечисления с другим классом.Мой класс содержит поле private Map<? extends Enum, Unit> myMap и инициализируется фабричным методом createMyClass:

public static MyClass <T extends Enum> myClass createMyClass(Class<T> x) {
    MyClass theClass = new MyClass() //constructor is private
    //...
    myMap = new HashMap<T, Unit>();
    for(T t : x.getEnumConstants())
        myMap.put(t, theClass.new Unit(t));
    //...
}

Класс Unit является (и должен быть, насколько я могу судить) внутренним классомMyClass.Когда я помещаю это в NetBeans, он жалуется на это сообщение:

метод put в интерфейсе java.util.Map<K,V> не может быть применен к данным типам
обязательно: захват # 4 из ? extends java.lang.Enum, MyClass.Unit
найдено: T, MyClass.Unit

Я понимаю (или, по крайней мере, думаю, что понимаю), как Коллекции должны быть очень осторожны с использованием подстановочных знаков, чтобы сохранить безопасность типов,но я не могу вспомнить, как T extends Enum не соответствует ? extends Enum.

Ответы [ 3 ]

3 голосов
/ 02 мая 2011

Попробуйте изменить объявление метода на:

public static <T extends Enum<T>> MyClass createMyClass(Class<T> x) {
}
0 голосов
/ 02 мая 2011

Что означает Map<? extends Enum, Unit>: «Ключ - это какой-то определенный класс, расширяющий Enum, но я не знаю, какой именно».И поскольку вы не знаете, какой это класс, вы не можете ничего добавить к такой карте, вы можете только извлечь из нее элементы и быть уверенными, что они Enum s.

Возможно, вам следует просто заявить, чтополе как Map<Enum, Unit> - это допустимо для всех Enum подклассов.

Это, кажется, самое распространенное заблуждение о перечислениях Java с большим отрывом - люди видят подстановочный знак ? и считают,использовать его для разрешения подклассов.

0 голосов
/ 02 мая 2011

Вы можете прочитать это Универсальный учебник .Это объясняет, почему это не работает в разделе 4 (подстановочные знаки).

Насколько я понимаю, ?Enum может быть любым перечислением, а не просто T или подклассом T.

...