无法将泛型转换为展开的嵌套类型 [英] Cannot convert generic to expanded nested type

查看:97
本文介绍了无法将泛型转换为展开的嵌套类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近,当我进入我无法解释的泛型演员问题时,我正在重构一个泛型方法。最后我意识到我可以完全没有T型(只是自己内联),但我仍然对转换失败的原因感到好奇。
我创建了这个最简单的示例来说明问题。



有人可以解释为什么转换失败并且解决方法有效吗?

  public< K,T extends List< K>> void castLists(List< T> list,K kForBinging){
Map< Integer,List< T>> map = mapSizeToList(list);
//类型不匹配:无法从地图转换< Integer,List< T>>映射<整数,列表<列表< K>>>
// Map< Integer,List< List< K>>> expandedMap = map;

//在接受答案后添加法律赋值:
Map< Integer,?扩展List <?扩展List< K>>> expandedMap = map;

//最初建议'work around'
Map< Integer,?> lessSpecific =地图;
@SuppressWarnings(unchecked)
Map< Integer,List< List< K>>> canCast =(Map // ...
}

public< A>映射<整数,列表< A>> mapSizeToList(List< A>列表){
Map< Integer,List< A>> map = Maps.newHashMap();
// ...
返回地图;


解决方案

我相信你需要 使用泛型的协变 ,然后才能执行此类操作。如果 T ,那么在Java中, 列表< K> 的子类型,它不暗示> 列表< T> 列表的一个子类型> List< List< K>> Map< Integer,List< T>> 映射<整数,列表<列表< K>>> 的子类型。这就是赋值错误的原因。



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

Recently I was refactoring a generic method when I got into generic casting issues I cannot explain. Finally I realized I could do without the T type altogether (just inline it myself), but I'm still curious as to why the convert fail. I created this minimal example to illustrate the issue.

Can someone explain me why the convert fails and the workaround works?

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;
}

解决方案

I believe you need Covariance with generics before you can do such things. This doesnt seem to be supported by Java.

i.e in Java, if T is a subtype of List<K>, it does NOT imply that List<T> is a subtype of List<List<K>> or that Map<Integer,List<T>> is a subtype of Map<Integer, List<List<K>>>. This is why the assignment errors out.

Covariance would allow you to do this because with it, if template parameters have a subclass-superclass relationship, the defined classes will also have the exact same relationship. This would make this assignment possible. Scala (among other (functional programming?) languages) supports covariance and its complement contravariance.

这篇关于无法将泛型转换为展开的嵌套类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆