I am trying to write a Java class, one part of which requires a mapping of the values of an unknown enum to another class. My class contains a field private Map<? extends Enum, Unit> myMap
private Map<? extends Enum, Unit> myMap
and is initialized with a factory method 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));
//...
}
The class Unit
is (and needs to be, as far as I can tell) an inner class of MyClass
. When I put this into NetBeans it complains with this message:
method
put
in interfacejava.util.Map<K,V>
cannot be applied to given types
required: capture #4 of? extends java.lang.Enum
? extends java.lang.Enum
,MyClass.Unit
found:T
,MyClass.Unit
I understand (or at least I think I do) how the Collections need to be very careful about wildcard usage to preserve type safety, but I can't think of how T extends Enum
fails to match ? extends Enum
? extends Enum
.
Try changing your method declaration to:
public static <T extends Enum<T>> MyClass createMyClass(Class<T> x) {
}
You can read this Generics Tutorial . It explains why this doesn't work in section 4 (Wildcards).
As far as I understand, ? extends Enum can be any enum, not just a T or subclass of T.
What Map<? extends Enum, Unit>
Map<? extends Enum, Unit>
means is "The key is some specific class that extends Enum, but I don't known which one". And since you don't know which class it is, you cannot add anything to such a Map, you can only get elements from it and be certain they are Enum
s.
You should probably just declare that field as Map<Enum, Unit>
- it will allow all Enum
subclasses just fine.
This seems to be the most common misunderstanding about Java enums by a huge margin - people see that ?
wildcard and think they have to use it to allow subclasses.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.