[英]Why does this compile? Java
我被告知以下编译:
Collection <? extends T> collection;
List<T> list;
collection = list; // Compiles
原因是“这就是 Java 开发人员定义它的方式”。 我想知道它背后的原理。 它可以编译,但在运行时可能会出现问题(例如,我们无法将任何对象添加到collection
)。
任何澄清将不胜感激。
编辑:我指的是泛型类型的Object
? extends T
? extends T
指向一个泛型类型T
的Object
。 这似乎有点违反直觉。
这是因为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
指向一个泛型类型T
的Object
。 这似乎有点违反直觉。
要理解这一点,您必须了解Collection<? extends T>
Collection<? extends T>
是。
它是:一个Collection
,其中包含扩展T
的特定但未知类型(由?
指示)的元素。
请注意,它不是扩展T
的任意(并且可能不同)类型的对象的Collection
(这是许多开发人员对通用通配符的误解)。
您可以将List<T>
分配给Collection<? extends T>
Collection<? extends T>
,因为List
是Collection
的子类型,而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.