Generics and inheritance: need a complex Map instance

dictionary, generics, inheritance, java

Solution

I don't think it's possible to encode this in the type, I'd do it with a custom class

class ClassMap<T> {
  private Map<Class<? extends T>, List<? extends T>> backingMap = new HashMap<>();

  public <E extends T> void put(Class<E> cls, List<E> value) {
    backingMap.put(cls, value);
  }

  @SuppressWarnings("unchecked")
  public <E extends T> List<E> get(Class<E> cls) {
    return (List<E>)backingMap.get(cls);
  }
}

It's safe to suppress warnings here as long as you don't leak the `backingMap` reference outside this class.

Problem

``` public abstract class Mother { } public class Daughter extends Mother { } public class Son extends Mother { } ``` I need a `Map` which keys are one of `Daughter` or `Son` classes, and which values are lists of objects of one of those two classes, respectively. For example: ``` /* 1. */ map.put(Daughter.class, new ArrayList<Daughter>()); // should compile /* 2. */ map.put(Son.class, new ArrayList<Son>()); // should compile /* 3. */ map.put(Daughter.class, new ArrayList<Son>()); // should not compile /* 4. */ map.put(Son.class, new ArrayList<Daughter>()); // should not compile ``` I tried `Map<Class<T extends Mother>, List<T>>`, but it does not compile. `Map<Class<? extends Mother>, List<? extends Mother>>` does compile, but the cases `3.` and `4.` do compile too while then shouldn't. Is it even possible?

Original source