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

时间:2012-12-20 09:55:20

标签: 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;
}

1 个答案:

答案 0 :(得分:6)

我相信你需要 Covariance with generics 才能做到这一点。 这似乎不受Java支持

即在Java中,如果TList<K>的子类型,则并不暗示 List<T>List<List<K>>的子类型或Map<Integer,List<T>>Map<Integer, List<List<K>>>的子类型。这就是赋值错误的原因。

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