无法将泛型转换为扩展嵌套类型

Sti*_*tim 6 java generics

最近我在进入通用铸造问题时重构了一个通用的方法,我无法解释.最后我意识到我可以完全没有T型(只是自己内联),但我仍然很好奇为什么转换失败.我创建了这个最小的例子来说明问题.

有人能解释一下为什么转换失败并且解决方法有效吗?

public <K, T extends List<K>> void castLists(List<T> list, K kForBinging) {
    Map<Integer, List<T>> map = mapSizeToList(list);
    // Type mismatch: cannot convert from Map<Integer,List<T>> to Map<Integer,List<List<K>>>
    // Map<Integer, List<List<K>>> expandedMap = map;

    // Added after accepting answer, legal assignment:
    Map<Integer, ? extends List<? extends List<K>>> expandedMap = map;

    // Originally proposed 'work around'
    Map<Integer, ?> lessSpecific = map;
    @SuppressWarnings("unchecked")
    Map<Integer, List<List<K>>> canCast = (Map<Integer, List<List<K>>>)lessSpecific;
    // ...
}

public <A> Map<Integer, List<A>> mapSizeToList(List<A> list) {
    Map<Integer, List<A>> map = Maps.newHashMap();
    // ...
    return map;
}
Run Code Online (Sandbox Code Playgroud)

Kar*_*k T 6

我相信在你做这些事情之前你需要协方差和泛型.这似乎不受Java支持.

即在Java中,如果T是子类型List<K>,则不暗示List<T>是子类型List<List<K>>或者Map<Integer,List<T>>是子类型Map<Integer, List<List<K>>>.这就是分配失误的原因.

协方差将允许您这样做,因为有了它,如果模板参数具有子类 - 超类关系,则定义的类也将具有完全相同的关系.这将使这项任务成为可能.Scala(以及其他(函数式编程?)语言)支持协方差及其补码逆变.