gpt4 book ai didi

java 。集合中的通配符

转载 作者:搜寻专家 更新时间:2023-11-01 02:46:48 25 4
gpt4 key购买 nike

java 。集合中的通配符

我在理解 Collections 中的通配符时遇到了很多困难,即使在阅读了 Stack Overflow 和各种教程网站中的类似帖子之后也是如此。我在下面做了一个非常简单的例子。你能解释一下我会如何在 Collection< myClass > 之间做出选择吗? , Collection< ? Extends MyClass > , 和 Collection< ? Super MyClass >

package z5;
import java.util.ArrayList;
public class Z5 {
public static class Animal{
}
public static class Mammal extends Animal{
}
public static class Reptile extends Animal{
}
public static class Lion extends Mammal{
}
public static class Tiger extends Mammal{
}
public static class Snake extends Reptile{
}
public static void main(String[] args) {
ArrayList<Mammal> catHouse1 = new ArrayList<Mammal>();
catHouse1.add(new Lion());
catHouse1.add(new Tiger());
catHouse1.add(new Mammal());
catHouse1.add(new Animal()); //ERROR
ArrayList<? super Mammal> catHouse2 = new ArrayList<Mammal>();
catHouse2.add(new Lion());
catHouse2.add(new Tiger());
catHouse2.add(new Mammal());
catHouse2.add(new Animal()); //ERROR
ArrayList<? extends Mammal> catHouse3 = new ArrayList<Mammal>();
catHouse3.add(new Lion()); //ERROR
catHouse3.add(new Tiger()); //ERROR
catHouse3.add(new Mammal()); //ERROR
catHouse3.add(new Animal()); //ERROR
ArrayList<Mammal> zooMammals = new ArrayList<Mammal>();
zooMammals.addAll(catHouse1);
zooMammals.addAll(catHouse2); //ERROR
zooMammals.addAll(catHouse3);
ArrayList<Animal> zooAnimals = new ArrayList<Animal>();
zooAnimals.addAll(catHouse1);
zooAnimals.addAll(catHouse2); //ERROR
zooAnimals.addAll(catHouse3);
}
}

在上面的示例中,我创建了类的层次结构。 Animal是Mammal和Reptile的父类(super class),Mammal是Lion和Tiger的父类(super class)。

我为动物园中的三个猫屋制作了 ArrayList。第一个只是 ArrayList< Mammal >。我可以添加任何哺乳动物类型或其子类的对象。

第二个是 ArrayList< ? super 哺乳动物>。我还可以添加 Mammal 类型的任何对象或其子类。

第三个是 ArrayList< ?延伸哺乳动物>。我不能添加任何东西。

最后,我将我的三个猫屋添加到动物园 Collection 中。 Animal 和 Mammal 是这里的主要父类(super class),无论接收方 ArrayList 持有哪种类型,行为都是相同的。ArrayList < Mammal > 和 ArrayList 可以添加到动物园中。ArrayList 不能。

这是我的问题:


1) 如果我想创建一个包含某个父类(super class)的所有子类的数组,为什么需要通配符?难道我不能只声明所有 ArrayList< Superclass > 并获得我需要的功能吗?

2) 我知道“< ? extends superclass >”接受父类(super class)及其所有子类。因此,<? extends Mammal >”接受 Mammals、Lions 和 Tigers。这听起来与“< Mammal >”完全一样。有什么区别?

3) 我读到“< ? super className >”接受任何类名的父类(super class)。这听起来不对。在上面的例子中,Lions 不是 Mammals 的父类(super class),但是“< ? super Mammal >”接受 Lions。 Animals 是 Mammals 的父类(super class),但是“< ? super Mammal >”不接受它。我想我那里的信息有误。

4) 如果“< ? extends superclass >”是只读的,我该如何开始填充它?拥有一个只能读取的空列表有什么意义?

5) 为什么 addAll 方法对“< ? super className >”不起作用?

我知道这些是基本问题,而且我知道之前已经有人回答过这些问题。我试图给出一个尽可能简单的代码示例,并希望能给我一个尽可能清晰的答案。提前感谢您提供的任何建议。

最佳答案

我不会详细介绍。

List<Animal>意思是:这个列表包含 Animal 的实例。所以你可以添加任何你想要的 Animal,并且当你从这个列表中获取元素时你一定会得到一个 Animal。

List<? extends Animal>意思是:这个列表是一个泛型列表,但是我们不知道泛型类型的类型。我们所知道的只是泛型类型是 Animal 或 Animal 的任何子类。所以它可能是 List<Animal> , 一个 List<Reptile>List<Lion> , 例如。但我们不知道。所以,当从这个列表中获取一个元素时,您一定会得到一个 Animal。但是你不会被允许在列表中添加任何东西,因为你不知道它的类型。如果您被允许添加一些东西,您可以将 Lion 存储在 List<Reptile> 中。 ,并且该列表将不再是类型安全的。

List<? super Animal>意思是:这个列表是一个泛型列表,但是我们不知道泛型类型的类型。我们所知道的只是泛型类型是 Animal,或者 Animal 的任何父类(super class)或超接口(interface)。所以它可能是 List<Animal>List<Object> , 例如。所以,当从这个列表中获取一个元素时,你可以肯定地说它是一个对象。不过,您可以肯定的是在此列表中添加您想要的任何动物,因为 List<Animal>List<Object>接受 Animal、Lion、Reptile 或 Animal 的任何子类。

大多数时候,您将这些通配符用作方法的参数。

当一个方法将列表作为参数并且只对从列表中读取感兴趣(即列表是生产者)时,您将使用 List<? extends Animal> .这使您的方法更具可重用性,因为它可以与 List<Animal> 一起使用, 还有一个 List<Reptile> , 一个 List<Lion>

当方法将列表作为参数并且只对向列表中添加元素感兴趣时(即列表是消费者),您将使用 List<? super Animal> .这使您的方法更具可重用性,因为它可以与 List<Animal> 一起使用, 还有一个 List<Object> .

此规则称为 PECS:Procucer:扩展;消费者: super

如果您的方法将列表作为参数并且必须从列表中获取和添加元素,您将使用 List<Animal> .

关于 java 。集合中的通配符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20165793/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com