public <? extends Animal> void takeThing(ArrayList<?> list)
public <T extends Animal> void takeThing(ArrayList<T> list)
为什么这句话错了?我的意思是为什么?
不能在前面使用?但是T
可以。有什么区别?
可能重复“When to use wildcards in Java Generics?”
这是这个问题的答案。但我不明白这是什么意思。 “如果你说void,则没有返回类型。如果你指定则返回类型。我不知道你可以指定返回类型或没有返回类型。”
答案 0 :(得分:5)
public void takeThing(ArrayList<? extends Animal> list)
表示&#34;使用Animal
&#34;的任何子类列表执行某些操作。
public <T extends Animal> void takeThing(ArrayList<T> list)
表示&#34;使用T
&#34;的某些特定子类(A.K.A. Animal
)列表执行某些操作。
如果我在第一个方法上调用list.get()
,我所知道的返回类型就是它扩展Animal
。在第二种方法中,如果我有另一个List<T>
实例,我知道无论类型T
是什么,两个列表都会接受相同的类型。
如果我说
,那就更进一步了Animal animal = list.get(0);
我再也不能说了
list.add(animal);
甚至在同一个列表中,因为我们没有引用泛型子类型。但是,如果我宣布List<T>
<T extends Animal>
,我现在可以说
T animal = list.get(0);
list.add(animal);
因为我们知道list
需要T
类型的元素。
答案 1 :(得分:4)
编写<T extends Animal>
绑定类型名称T
,以便稍后可以在定义中引用它(包括在参数列表中)。
如果您写了<? extends Animal>
,那么您没有为该类型命名。因此,您以后不能参考它。您之后不能将其称为?
,因为这可能是不明确的(如果您有两个类型参数会怎么样?)。
Java禁止您编写public <?> ...
,因为这样的声明是无用的(类型参数未命名,因此无法使用)。