class P {
}
class Q extends P {
}
class R extends Q {
}
class S extends R {
}
public class Manager {
public static void main(String[] args) {
X<? super R> x4 = null;
x4.test(new S());
x4.test(new R());
x4.test(new P());//compile time error
}
}
class X<A> {
void test(A obj) {
}
}
//表示R的R或超类,即P,Q或Object,但是为什么我在程序中指定的在线上得到编译时错误。
答案 0 :(得分:4)
以下是JLS
中的一些规则类型参数
T1
据说包含另一个类型参数T2
, 写T2 <= T1
,如果T2
表示的类型集可证明是a 反射和反射下由T1
表示的类型集的子集 传递性关闭以下规则(其中<:
表示子类型 (§4.10)):
? super T <= ? super S if S <: T
? super T <= ?
? super T <= ? extends Object
T <= ? super T
符号
X<? super R> x4 = null;
使用通用通配符类型参数声明X
,其下限为R
。
根据上述规则和变量声明,我们可以确定通配符涵盖R
和R
本身的所有子类型。 S
是R
的子类型,R
是R
,P
不是R
的子类型。
以下可能会产生混淆。你可以做到
X<? super R> x4 = new X<P>();
因为P
是R
的超类。但是,当您想要使用类X
的类型参数时,您只知道它必须至少是R
。
进一步阅读:
答案 1 :(得分:0)
您可以传递扩展R的对象,即R或S,但不能传递它的父对象。 R是任何传递实例的超类!