简体   繁体   中英

Java generics for Enum types

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 interface java.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM