繁体   English   中英

为什么会这样编译? 爪哇

[英]Why does this compile? Java

我被告知以下编译:

Collection <? extends T> collection;
List<T> list;
collection = list; // Compiles

原因是“这就是 Java 开发人员定义它的方式”。 我想知道它背后的原理。 它可以编译,但在运行时可能会出现问题(例如,我们无法将任何对象添加到collection )。

任何澄清将不胜感激。

编辑:我指的是泛型类型的Object ? extends T ? extends T指向一个泛型类型TObject 这似乎有点违反直觉。

这是因为Collection是一个接口。 List也是一个extends Collection 接口的接口。

根据Object oriented principles ,父类引用可以持有子类引用!

例如,如果我有以下

class Parent {
//Some code
}

class Child extends Parent {
//Some code
}

我可以做这个

Parent parentObject = new Child();
parentObject.childMethod();  or parentObject.parentMethod(); 

https://docs.oracle.com/javase/8/docs/api/java/util/List.html这个文档可以提供帮助!

编辑:我指的是泛型类型的Object ? extends T ? extends T指向一个泛型类型TObject 这似乎有点违反直觉。

要理解这一点,您必须了解Collection<? extends T> Collection<? extends T>是。

它是:一个Collection ,其中包含扩展T的特定但未知类型(由?指示)的元素。

请注意,它不是扩展T的任意(并且可能不同)类型的对象的Collection (这是许多开发人员对通用通配符的误解)。

您可以将List<T>分配给Collection<? extends T> Collection<? extends T> ,因为ListCollection的子类型,而List<T>的元素确实是类型? extends T ? extends T (在这种特殊情况下,实际类型是类型T本身,但仍匹配“扩展T的某些未知类型? ”)。

请注意,使用通配符实际上会丢弃有关集合元素的确切类型的信息——它使 Java 忘记了确切的类型,只会让它记住它是扩展T的未知类型。

您不能将任何内容添加到通配符参数化类型的集合中,例如Collection<? extends T> Collection<? extends T> ,正是因为缺少有关元素确切类型的信息。 如果您尝试将元素添加到此类集合中,编译器将无法检查您添加的元素的类型是否正确。

如果您尝试在Collection<? extends T>上调用add() Collection<? extends T>你会得到一个编译错误,说明你添加的对象的类型不是“捕获... of ? extends T ”。 这基本上意味着:“我无法检查您要添加的对象是否属于未知类型? extends T ”。

由于类型擦除,在运行时也无法检查类型:类型参数在 Java 中是编译时唯一的东西,在运行时它们不再存在,所以也没有足够的信息来检查你正在添加的元素是正确的类型。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM