通配符和'T'之间有什么区别?

时间:2014-06-10 07:05:26

标签: java

    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,则没有返回类型。如果你指定则返回类型。我不知道你可以指定返回类型或没有返回类型。”

2 个答案:

答案 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 <?> ...,因为这样的声明是无用的(类型参数未命名,因此无法使用)。