通配符的局限性在于它们会破坏
T extends X<T>类型参数允许的递归表达式。基于以下几点,我们知道您要执行的操作是安全的:
r.o
是类型T
(由声明R
),是或扩展N<T>
。- 该方法
p
采用类型的参数T
(由声明p
),该参数也为或扩展N<T>
。 - 因此,即使
r
键入为R<?>
,从p(r.o)
理论上讲呼叫也应该合法。
这可能是eclipse编译器的原因(已知它会为javac没有的某些细微差别提供正确的余量)。
假设您想使用javac进行编译并且不能
v像您提到的那样更改签名,那么您可以做的最好的事情就是使用原始类型,该类型“选择退出”泛型类型检查:
public void v(final R<?> r) { //necessary to placate javac - this is okay because [insert above reasoning] @SuppressWarnings("rawtypes") N nRaw = r.o; p(nRaw);}


