我对Java的泛型类型中使用通配符有疑问:List<? extends Set>和之间的基本区别是List<T extends Set>什么?我什么时候使用?
两个原因:
为了避免不必要的演员:
你必须使用这种T情况的变体:
public <T extends Set> T firstOf(List<T> l) {
return l.get(0);
}
Run Code Online (Sandbox Code Playgroud)
随着?这将成为:
public Set firstOf2(List<? extends Set> l) {
return l.get(0);
}
Run Code Online (Sandbox Code Playgroud)
...它不向该firstOf方法的调用者提供相同数量的信息.第一个版本允许调用者执行此操作:
SubSet first = firstOf(listOfSubSet);
Run Code Online (Sandbox Code Playgroud)
而对于第二个版本,您被迫使用强制转换来进行编译:
SubSet first = (SubSet)firstOf(listOfSubSet);
Run Code Online (Sandbox Code Playgroud)
要强制匹配参数类型:
public <T extends Set> boolean compareSets(List<T> a, List<T> b) {
boolean same = true;
for(T at : a) {
for (T bt: b) {
same &= at.equals(bt);
}
}
return same;
}
Run Code Online (Sandbox Code Playgroud)
没有直接等效使用?而不是T为此.需要注意的是,由于Java的单调度,在上面的版本,编译器会调用at的equals(T)方法,这很可能不同于atS' equals(Set)或equals(Object)方法.
这里的区别在于,在第二个版本中,您有一个类型变量,它T引用包含的特定子类型。当您需要确保其他内容与列表中包含的类型类型相同时,您需要这样做。几个简单的例子:SetList
// want to ensure that the method returns the same type contained in the list
public <T extends Set> T something(List<T> list) {
...
}
// want to ensure both lists contain the exact same type
public <T extends Set> List<T> somethingElse(List<T> first, List<T> second) {
...
}
Run Code Online (Sandbox Code Playgroud)
简单规则:T extends Foo如果两个地方需要相同的类型,请在方法签名中使用类型变量。方法参数各在一个地方,方法返回类型在另一处。? extends Foo如果您只需要确保在一个地方处理“某种东西”,请使用通配符Foo。
另外:不要使用原始类型Set。
| 归档时间: |
|
| 查看次数: |
1208 次 |
| 最近记录: |