我想知道为什么不允许在java超类中使用通配符作为模板参数。当我用不同的模板参数多次实现泛型接口时,我遇到了这个问题:
interface A<THIS extends A<THIS>> {...}
interface B<THIS extends B<THIS>> {...}
interface C extends A<C> {...}
interface D extends B<D>, C {...}
在这种情况下A
被C
和D
实施两次,导致错误。
但在这种特殊情况下,我不关心A
和B
的确切类型,当它们被扩展时,所以使用?
作为参数会很酷:
interface A<THIS extends A<THIS>> {...}
interface B<THIS extends B<THIS>> {...}
interface C extends A<?> {...}
interface D extends B<?>, C {...}
修改:A
和A<?>
在扩展时都不是A<THIS extends A<THIS>>
的可行子代码。
然而,实际工作的是使用原始类型。这种行为正是我对通配符的期望。而且它也是类型。
interface A<THIS extends A<THIS>> {
THIS foo();
}
interface B<THIS extends B<THIS>> {
@Overrid THIS foo();
}
interface C extends A {
@Overrid C foo();
}
interface D extends B, C {
@Overrid D foo();
}
原因是有关于使用原始类型的警告,但与之前的错误相比,这是可以的。那么使用通配符的区别在哪里?显然,您无法将特定参数设置为T<?,X>
之类的通配符。但对于任何类型T<P1,...,Pn>
,原始类型T
的行为都与T<?,...,?>
相似,对吗?