Is Listlt;Doggt; a subclass of Listlt;Animalgt;? Why are Java generics not implicitly polymorphic?(是列表lt;狗gt;Listlt;Animalgt; 的子类?为什么 Java 泛型不是隐式多态的?)
问题描述
我对 Java 泛型如何处理继承/多态感到有些困惑.
I'm a bit confused about how Java generics handle inheritance / polymorphism.
假设以下层次结构 -
动物(父母)
狗 - 猫(儿童)
所以假设我有一个方法doSomething(Listanimals)
.根据继承和多态性的所有规则,我会假设 List<Dog>
is 一个 List 和一个
List<Cat>
is List<Animal>
- 所以任何一个都可以传递给这个方法.不是这样.如果我想实现这种行为,我必须通过说 doSomething(List extends Animal> animals)
明确告诉该方法接受 Animal 的任何子类的列表.
So suppose I have a method doSomething(List<Animal> animals)
. By all the rules of inheritance and polymorphism, I would assume that a List<Dog>
is a List<Animal>
and a List<Cat>
is a List<Animal>
- and so either one could be passed to this method. Not so. If I want to achieve this behavior, I have to explicitly tell the method to accept a list of any subclass of Animal by saying doSomething(List<? extends Animal> animals)
.
我了解这是 Java 的行为.我的问题是为什么?为什么多态性一般是隐含的,而泛型却必须指定?
I understand that this is Java's behavior. My question is why? Why is polymorphism generally implicit, but when it comes to generics it must be specified?
推荐答案
不,List
不是 List
代码>.考虑一下你可以用 List<Animal>
做什么 - 你可以向其中添加 any 动物......包括一只猫.现在,你能合乎逻辑地将一只猫添加到一窝小狗中吗?绝对不是.
No, a List<Dog>
is not a List<Animal>
. Consider what you can do with a List<Animal>
- you can add any animal to it... including a cat. Now, can you logically add a cat to a litter of puppies? Absolutely not.
// Illegal code - because otherwise life would be Bad
List<Dog> dogs = new ArrayList<Dog>(); // ArrayList implements List
List<Animal> animals = dogs; // Awooga awooga
animals.add(new Cat());
Dog dog = dogs.get(0); // This should be safe, right?
突然间你有一只非常困惑的猫.
Suddenly you have a very confused cat.
现在,您不能将 Cat
添加到 List 因为你不知道它是一个
List<Cat>
.您可以检索一个值并知道它将是一个 Animal
,但您不能添加任意动物.List 的情况正好相反.super Animal>
- 在这种情况下,您可以安全地添加一个 Animal
到它,但是您不知道可以从中检索到什么,因为它可能是一个 列出<对象>
.
Now, you can't add a Cat
to a List<? extends Animal>
because you don't know it's a List<Cat>
. You can retrieve a value and know that it will be an Animal
, but you can't add arbitrary animals. The reverse is true for List<? super Animal>
- in that case you can add an Animal
to it safely, but you don't know anything about what might be retrieved from it, because it could be a List<Object>
.
这篇关于是列表<狗>List<Animal> 的子类?为什么 Java 泛型不是隐式多态的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:是列表<狗>List<Animal> 的子类?为什么 Java 泛型不是隐式多态的?
基础教程推荐
- 首次使用 Hadoop,MapReduce Job 不运行 Reduce Phase 2022-01-01
- 如何对 HashSet 进行排序? 2022-01-01
- 在螺旋中写一个字符串 2022-01-01
- Spring Boot Freemarker从2.2.0升级失败 2022-01-01
- 由于对所需库 rt.jar 的限制,对类的访问限制? 2022-01-01
- 如何使用 Eclipse 检查调试符号状态? 2022-01-01
- 如何在不安装整个 WTP 包的情况下将 Tomcat 8 添加到 Eclipse Kepler 2022-01-01
- 如何使用 Stream 在集合中拆分奇数和偶数以及两者的总和 2022-01-01
- Java 中保存最后 N 个元素的大小受限队列 2022-01-01
- 如何强制对超级方法进行多态调用? 2022-01-01