准备OCPJP 6考试(这就是我使用Java 1.6编译器的原因)我发现了一些关于Java Generics的不清楚的事情。 请考虑以下代码:
class A<K extends Number> {
public <V> V useMe1(A<? super V> a) { // OK
return null;
}
public <V> V useMe2(A<? extends V> a) { // OK
return null;
}
public <V> V useMe3(A<V> a) { // ERROR, but why, since 2 above were ok
return null;
}
}
当我尝试编译代码(使用1.6编译器)时,我收到错误:
类型参数V不在其绑定范围内
尽管上面的代码不可用,但我想知道为什么编译器认为类型<? super V>
和<? extends V>
匹配类类型绑定但<V>
不匹配(因为V匹配这两个边界。)
我不打算修改该代码,我想了解它。代码取自样本OCPJP 6考试问题&#34;哪一行将编译?&#34;
答案 0 :(得分:1)
第三个useMe3
失败,因为V
因其声明extend Number
缺少界限而无法保证<V>
。由于参数声明为A<V>
,因此没有scape,V
必须扩展Number
,并且Java语言要求程序员在这种情况下明确说明。
事实上这很简单,也许不太明显为什么其他两个可能有效。
通过在他们的参数类型定义中使用?
,即使extend Number
本身是一个不受与{相关的任何特定约束限制的小修道院限制的小修道院',它也有可能与V
兼容。 {1}}。
您必须注意Number
不再影响extend Number
,而是V
无论如何。换句话说,有一个未知的类由?
代表,必须?
,并且在方法extend Number
之上,例如,它必须是超级的useMe1
其中V
将由调用该方法的代码确定。
对于V
来说,这可能更有意思,其中useMe2
可以有效地与V
完全无关。例如:
Number
在上面的interface FooInterface { ... }
class MyNumber extends Number implements FooInterface { ... }
A<?> subject = ...;
A<MyNumber> param = ...;
FooInterface foo = subject.useMe2(param);
调用中,useMe2
V
与FooInterface
无关,Number
in ?
MyNumber
}}。 MyNumber
受限于A
绑定到扩展Number
的类型参数以及useMe2
中参数的类型参数定义,以扩展FooInterface
但V
1}}本身完全不受限制。