Java 为什么可以';我投了一个集合<;通用食品>;收藏<;GenericFoo<&燃气轮机&燃气轮机;

Java 为什么可以';我投了一个集合<;通用食品>;收藏<;GenericFoo<&燃气轮机&燃气轮机;,java,generics,Java,Generics,问题的关键是,为什么这会导致编译时错误 List<Collection> raws = new ArrayList<Collection>(); List<Collection<?>> c = raws; // error 错误是因为GenericFoo.class具有类型class,而不是class。首先,原始类型和通配符类型有很大不同。首先,raw类型完全删除所有通用信息 所以我们有List和List,其中x不是y。这当然不是子类型关系 不过

问题的关键是,为什么这会导致编译时错误

List<Collection> raws = new ArrayList<Collection>();
List<Collection<?>> c = raws; // error

错误是因为
GenericFoo.class
具有类型
class
,而不是
class。首先,原始类型和通配符类型有很大不同。首先,raw类型完全删除所有通用信息

所以我们有
List
List
,其中x不是y。这当然不是子类型关系

不过,你可以要求允许演员出演。但请阅读 ,然后告诉我你想给它添加更多的内容:)浏览整个页面,事实上,这是一个文字长城,只是为了铸造


记住,这只是整个效果中的第一个涟漪。关于
列表
列表
等相关内容如何:(但我不认为你在问规范,对吗?无论如何,我个人不认为有实际原因不允许转换。)感谢@Radiodef的链接。但是,是的,我不是在问规范,而是在问理论——当前的事态是否真的给我们带来了一些保护,或者它是否只是类型系统碰巧没有涵盖的一个边缘案例。实际上,你的问题归结为“为什么
集合
不包含
集合
?”(在JLS意义上的遏制)。我们需要深入研究JLS作者的讨论,以获得他们意图的真实答案。然而,我将推测一个答案:因为当前的遏制规则更容易实施,没有像这样的特殊例外。换句话说,没有理由不改变公约,它只是一个特殊的例外一种试图避免特殊异常的语言规范。但这只是一种猜测。@sprinter好吧,正如我在上面的后一个链接中指出的,它对类型系统玩了一个有趣的游戏。
Class
Class
的超类型,但是
List
将是
List@Radiodef是的,我同意在大多数情况下都能很好地避免此类有趣的游戏。在这种情况下,规范可以更改(对实现进行相应的努力,但不会对编码人员造成太大的危险)但是,考虑到它可能解决的所有问题都有其他解决方案,为什么要增加复杂性而只获得很少的收益呢?我不确定我是否同意使规范复杂化是一个问题。看看第18章。这都是全新的。但涟漪效应是真实的。当然,这一切都可以修复(规范简化了…)完全删除原始类型。@Radiodef-没问题吗?说起来容易:)第18章是一个现代奇迹,它的完成令人惊讶,而且大部分是由一个人完成的。大概只有3个男孩和1个女孩理解它;我敢肯定,他们在完成编译器的编码后就不再这么做了,哈哈。我也不确定,如果规范变得更复杂一点,如果它可以让语言变得更简单一点,那会是一件可怕的事情。但是你提到的连锁反应是一个很好的反驳,它实际上使语言更简单。
List<Integer> ints = new ArrayList<Integer>();
List<Number> nums = ints; // compile-time error
nums.add(Double.valueOf(1.2));
Integer i = ints.get(0); // ClassCastException
List<Collection> rawLists = new ArrayList<Collection>();
List<Collection<?>> wildLists = rawLists; // compile-time error

// scenario 1: add to raw and get from wild
rawLists.add(new ArrayList<Integer>());
Collection<?> c1 = wildLists.get(0);
Object o1 = c1.iterator().next();

// scenario 2: add to wild and get from raw
wildLists.add(new ArrayList<String>());
Collection c2 = rawLists.get(0);
Object o2 = c2.iterator().next();
public Collection<T> readJsons(List<String> jsons, Class<T> clazz) {
    List<T> list = new ArrayList<T>();
    for (String json : jsons) {
        T elem = jsonMapper.readAs(json, clazz);
        list.add(elem);
    }
    return list;
}

// call site
List<GenericFoo<?>> foos = readJsons(GenericFoo.class); // error