简体   繁体   中英

How to get a type with multiple generic types to match the type parameters?

例如,说我想要一个Map<Class<?>, List<?>> ,这样我就可以放入一个类中并获得该类型的列表-是否可以替换问号以实现这一点? ?

You can do the trick if you delegate type check to the method:

private class TypedMap {
    private Map<Class<?>, List<?>> map = new HashMap<>();

    public <T> void put(Class<T> key, List<T> value) {
        map.put(key, value);
    }

    @SupressWarnings("unchecked")
    public <T> List<T> get(Class<T> clazz) {
        return (List<T>) map.get(clazz);
    }
}
  • Wildcard ? in map declaration does not ensure that key Class<?> and value List<?> would be of the same type. Method put() ensures that. You can not declare map as Map<Class<T>, List<T>> if your class is not generic - that's why you have to use a method.

  • Get method is unchecked. The cast is safe if entries are added with put() method. (There's still a problem with raw types - but this is unavoidable)

  • You can add more methods to TypedMap class, but remember about this restrictions.


public static void main(String[] args) {
    TypedMap map = new TypedMap();
    List<Cat> cats = new ArrayList<>();
    List<Dog> dogs = new ArrayList<>();
    adder.put(Cat.class, cats);
    adder.put(Dog.class, dogs);

    adder.put(Cat.class, dogs); // compilation error
}

Java doesn't completely enforce this, but one way to at least get a warning about it, is by using encapsulation:

public class MyClass {
    // private, private, private
    private Map<Class<?>, List<?>> myMap;

    public <T> void put(Class<T> clazz, List<T> list) { // both must have the same T.
        myMap.put(clazz, list);
    }
    ...
}

You can still break this by doing something like:

MyClass mc = new MyClass();
Class c = Main.class;       
List<String> l = new ArrayList<String>();       
mc.put(c, l);

But you'll at least get a warning about unchecked conversion of c to Class<String> . And the unchecked invocation of MyClass::put

Not sure what you're trying to accomplish here, but Map<Class<T>, List<T>> would be the closest thing. The T is one single class type, though, so you can't put multiple classes into one Map .

You'll get a ClassCastException if you try to put objects of different classes into the same Map .

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