[英]java Generics Wildcard
我有一个关于在 Java 的泛型类型中使用通配符的问题: List<? extends Set>
List<? extends Set>
和List<T extends Set>
? 我什么时候用?
两个原因:
为避免不必要的强制转换:
对于这样的情况,您必须使用T
变体:
public <T extends Set> T firstOf(List<T> l) {
return l.get(0);
}
与?
这将变成:
public Set firstOf2(List<? extends Set> l) {
return l.get(0);
}
...这不会为firstOf
方法的调用者提供相同数量的信息。 第一个版本允许调用者这样做:
SubSet first = firstOf(listOfSubSet);
而在第二个版本中,您必须使用强制转换来使其编译:
SubSet first = (SubSet)firstOf(listOfSubSet);
强制匹配参数类型:
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;
}
没有直接等效的使用?
而不是T
。 请注意,由于 Java 的单调度,在上述版本中,编译器将调用at
的equals(T)
方法,这可能与at
的equals(Set)
或equals(Object)
方法有很大不同。
这里的不同之处在于,在第二个版本中,您有一个类型变量T
,它引用List
包含的Set
的特定子类型。 在需要确保其他内容与列表中包含的类型相同的情况下,您需要这样做。 几个简单的例子:
// 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) {
...
}
简单规则:如果在两个地方需要相同的类型,则在方法签名中使用类型变量T extends Foo
。 方法参数在一个地方,方法返回类型在另一个地方。 使用通配符? extends Foo
? extends Foo
如果您只需要确保在一个地方处理“某物是Foo
”。
另外:不要使用原始类型Set
。
你使用List<? extends Set>
List<? extends Set>
当你声明一个变量时。 例如:
List<? extends Number> l = new ArrayList<Integer>();
List<T extends Number>
可以在 class 或方法声明中使用。 这将允许您写 T 而不是<? extends Number>
<? extends Number>
稍后在 function 中。
public <T extends Number> int addAll(List<T> list) {
int result = 0;
for (T t : list) {
result += t.intValue();
}
return result;
}
我们使用通配符来指定类型元素匹配任何内容。 ?
代表未知类型。
List<? extends Set>
List<? extends Set>
是有界通配符的一个示例,它声明列表可以接受Set
的任何子类型(例如HashSet
) List<T extends Set>
另一方面是允许T
绑定到扩展的类型Set
。
当我需要数据集合时,我使用通配符,而不管它的确切类型。
通配符类型G<? extends A>
G<? extends A>
是任何G<Ai>
的超类型,其中Ai
是A
的子类型
换句话说, G<? extends A>
G<? extends A>
是G<A0>, ..., G<An>
的联合类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.