Search code examples
javagenericstype-erasureraw-typesenumset

Problems when operating on Map<Class<?>, Object> in Java


public class MyClass<T> {

    private Map<Class<?>, Object> member;

    public <E> void putEnumSet(Class<E> enumSetType, E enumSet) {
        this.member.put(enumSetType, enumSetType.cast(enumSet));
    }

    public <E> E getEnumSet(Class<E> enumType) {
        return enumType.cast(this.member.get(enumType));
    }

};

public enum Category {
    // ...
};

The member in MyClass is used to store several kinds of EnumSet with different Enum type. While implementing relative methods, I meet some problems: when I try to call the method like this:

public static void main(String[] args) {

    EnumSet<Category> set = EnumSet.noneOf(Category.class);

    MyClass<Word> newClass = new MyClass<Word>();
    newClass.putEnumSet(set.getClass(), set);

}

Here comes the error:

The method putEnumSet(Class<E>, E) in the type MyClass<Word> is not applicable for the arguments (Class<capture#1-of ? extends EnumSet>, EnumSet<Category>)

How to deal with this problem? I think it may come from raw type or type erasure, but I do not know the main reason. Thanks.


Solution

  • How to deal with this problem?

    E extends EnumSet<E>
    

    This is very confusing as it says you have to have a element E which must extend EnumSet<E> i.e. you need an element type which is itself an EnumSet of E


    You have a problem that all EnumSet classes are the same at runtime. I.e. there is only one EnumSet.class. You are better off recording the class of elements.

    public class MyClass {
    
        private Map<Class, Set> member;
    
        public <E> void putEnumSet(Class<E> elementType, Set<E> enumSet) {
            this.member.put(elementType, enumSet);
        }
    
        public <E> Set<E> getEnumSet(Class<E> elementType) {
            return (Set<E>) this.member.get(elementType));
        }
    };