什么时候在 Java 泛型中使用通配符? [英] When to use wildcards in Java Generics?
问题描述
这是来自 HeadFirst Java:(第 575 页)
this is from HeadFirst Java: ( page 575 )
这个:
public <T extends Animal> void takeThing(ArrayList<T> list)
做同样的事情:
public void takeThing(ArrayList<? extends Animal> list)
所以这是我的问题:如果它们完全相同,我们为什么不写
So here is my question: if they are exactly same, why don't we write
public <? extends Animal> void takeThing(ArrayList<?> list)
或
public void takeThing(ArrayList<T extends Animal> list)
此外,什么时候使用 ?而不是带有泛型的方法声明(如上)中的 T ,或用于类声明?有什么好处?
Also, when would it be useful to use a ? instead of a T in a method declaration ( as above ) with Generics, or for a Class declaration? What are the benefits?
推荐答案
两者的区别
public <T extends Animal> void takeThing(ArrayList<T> list)
和
public void takeThing(ArrayList<? extends Animal> list)
是在前一种方法中,您可以在方法中将T"称为给定的具体类.在第二种方法中你不能这样做.
is that in the former method you can refer to "T" within the method as the concrete class that was given. In the second method you cannot do this.
这里有一个更复杂的例子来说明这一点:
Here a more complex example to illustrate this:
// here i can return the concrete type that was passed in
public <T extends Animal> Map<T, String> getNamesMap(ArrayList<T> list) {
Map<T, String> names = new HashMap<T, String>();
for (T animal : list) {
names.put(animal, animal.getName()); // I assume there is a getName() method
}
return names;
}
// here i have to use general Animal
public Map<Animal, String> getNamesMap(ArrayList<? extends Animal> list) {
Map<Animal, String> names = new HashMap<Animal, String>();
for (Animal animal : list) {
names.put(animal, animal.getName()); // I assume there is a getName() method
}
return names;
}
使用第一种方法,如果你传入一个猫列表,你会得到一个以猫为键的地图.第二种方法总是返回一个带有通用 Animal 键的 Map.
With the first method if you pass in an List of Cats you get a Map with Cat as key. The second method would always return a Map with general Animal key.
顺便说一下,这不是有效的 java 语法:
By the way this is not valid java syntax:
public <? extends Animal> void takeThing(ArrayList<?> list)
使用这种形式的泛型方法声明,您必须使用有效的 java 标识符而不是?".
Using this form of generic method declaration you have to use a valid java identifier and not "?".
? extends Type"形式仅适用于变量或参数类型声明.在通用方法声明中,它必须是标识符扩展类型",因为您可以在方法中引用标识符".
The form "? extends Type" only applies to variable or parameter type declaration. Within a generic method declration it has to be "Identifier extends Type" as you are able to refer to the "Identifier" from within your method.
这篇关于什么时候在 Java 泛型中使用通配符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!