例如:
public String add(Set<?> t){
...;
}
public <T> String add(Set<T> t){
...;
}
Run Code Online (Sandbox Code Playgroud)
第一个使用通配符泛型; 第二种是通用方法的正常形式.有什么不同?
在什么情况下我们需要通配符泛型,而不是普通的泛型?
new*_*cct 12
这是需要通配符的情况.此方法采用a List<List<?>>,即列表列表.该方法可以向其中添加不同组件类型的列表:
public void foo(List<List<?>> t) {
t.add(new ArrayList<String>());
t.add(new ArrayList<Integer>());
}
Run Code Online (Sandbox Code Playgroud)
您不能使用没有通配符的泛型类型参数来执行此操作.例如,以下内容不起作用:
public <T> void foo(List<List<T>> t) {
t.add(new ArrayList<String>()); // does not compile
t.add(new ArrayList<Integer>()); // does not compile
}
Run Code Online (Sandbox Code Playgroud)
Mic*_*ski 11
由于添加了对泛型的支持,因此使用参数化类型而不提供类型参数通常会导致编译器警告.另一方面,有些情况下你根本不关心类型参数是什么(即你不在任何地方使用这种类型),或者更糟糕的是,你可能根本不知道什么T是什么,并且使用<?>让你表达这一点而不会导致编译器警告.
"不关心"案例的可能用例(为简洁起见非常简单,但你明白了):
public void clearList(List<?> list) {
list.clear();
}
Run Code Online (Sandbox Code Playgroud)
"不知道"案例的一个例子:来自Class类的实际方法签名:
static Class<?> forName(String className);
Run Code Online (Sandbox Code Playgroud)
这里该方法返回某种Class类型的对象.Class是通用的但当然你不知道类型,因为它取决于className在运行时解析的参数.所以你不能放在T这里因为T在编译时不知道(即使对于特定的调用站点),并且仅使用Class不带类型参数将是一种不好的做法并导致编译器警告.
调用方法没有区别。
在第二种方法 ( add(Set<T>)) 中,您可以创建类型的变量T:
public <T> String add(Set<T> t){
T item = t.iterator().next();
//....
}
Run Code Online (Sandbox Code Playgroud)
这为您提供了一些额外的类型检查。在第一种方法中,您只能使用Object.
| 归档时间: |
|
| 查看次数: |
435 次 |
| 最近记录: |