Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中的泛型(和通配符)_Java_List_Generics_Collections_Wildcard - Fatal编程技术网

Java中的泛型(和通配符)

Java中的泛型(和通配符),java,list,generics,collections,wildcard,Java,List,Generics,Collections,Wildcard,我正在读的一本关于Java的书告诉我,以下两段代码是等效的: public <T extends Animal> void takeThing(ArrayList<T> list) public void takeThing(ArrayList<? extends Animal> list); 公共作废处理(ArrayList列表) 公共无效接受(ArrayList) 这是否意味着如果我有一个列表(或其他集合类型?),我就不能让它们同时接受多态参数并重新调

我正在读的一本关于Java的书告诉我,以下两段代码是等效的:

public <T extends Animal> void takeThing(ArrayList<T> list)

public void takeThing(ArrayList<? extends Animal> list);
公共作废处理(ArrayList列表)
公共无效接受(ArrayList)
这是否意味着如果我有一个列表(或其他集合类型?),我就不能让它们同时接受多态参数并重新调整大小

没有

这两段代码并不完全相同。在第一行中,方法
takeThing
有一个类型参数
T
。在第二行中,您使用了一个通配符


当您使用第一个版本时,您将指定将用于
T
的具体类型。因为具体类型是已知的,所以添加到列表中没有问题


在第二个版本中,您只是说“
list
是一个
ArrayList
,它包含一些扩展了
Animal
”的未知类型的对象。确切的类型是什么还不清楚。您无法将对象添加到这样的列表中,因为编译器没有足够的信息(它不知道实际的类型是什么)检查是否允许向列表中添加内容。

通常,如果向列表中添加内容涉及一个只接受列表而不接受要添加内容的方法,那么您将在其他地方拥有一个
动物
,并且您希望将其添加到列表中。在这种情况下,必须声明您的方法,以便所有列表它接受的类型允许向其中添加
动物
。这必须是
列表
动物
的一些超类型的列表。它不可能是
列表
-您添加的元素可以是任何
动物


这就是下限的概念和关键字
super
。类型声明
list在这两种情况下都不能添加任何内容到列表中,因为您没有指定下限。只有
扩展了
。如果使用
super
,您可以向该列表添加元素。但在这种情况下,您可以添加元素仅传递超级类型列表。从技术上讲,两种情况下都可以添加
null
。@MarkoTopolnik任何一种情况下都可以添加某些内容。
null
一种情况下,也可以添加可能存在的元素的副本。要做到这一点,第二种情况下,只需捕获通配符。我经常对缺乏意识感到惊讶当涉及到通配符捕获时。@Jesper您可以从第二个方法调用第一个方法(假设它们不冲突)。这会将通配符捕获为
T
。注意第一个方法声明中的
。我们不能在该列表中添加新值。当然,如果新值不是空的话。@RohitJain,但这本身并不是不能向列表中添加任何内容的原因。问题是从何处获取
T
对象列表。例如,它可以正常工作:
public void takeThing(ArrayList list,te){list.add(e);}
@Jesper..但是如果您要添加在该方法中创建的新元素,那么您将无法添加。“当您使用第一个版本时,您将指定T将使用什么具体类型。因为具体类型是已知的,所以添加到列表中没有问题。“这没有意义。所选类型参数仅在调用方的作用域中已知。但当您谈论添加到列表时,它在函数内部,因此您不知道t是什么,它可能是任何东西。