准备 OCPJP 6 考试(这就是我使用 Java 1.6 编译器的原因)我注意到我对 Java 泛型有一些不清楚的地方。
考虑以下代码:
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 编译器)时,出现错误:
type parameter V is not within its bound
尽管上面的代码不可用,但我想知道为什么编译器认为类型 <? super V>
和 <? extends V>
匹配绑定(bind)的类类型但是 <V>
不是(因为 V 匹配这两个边界)。
我不打算修改那段代码,我想了解它。该代码取自样本 OCPJP 6 考试问题,询问“哪一行将编译?”
第三个,useMe3
, 失败为 V
不保证 extend Number
鉴于其声明缺乏界限<V>
.由于参数声明为 A<V>
没有景观,V
必须扩展 Number
在这种情况下,Java 语言要求程序员明确声明。
这实际上是最简单的一个,也许其他两个可能起作用的原因不太明显。
通过使用 ?
在他们的参数类型定义中,您提供了与 extend Number
兼容的机会即使V
本身是一个修道院,不受与 Number
相关的任何特定约束的限制。 .
你必须注意到 extend Number
不影响 V
不再是?
不管那是什么。换句话说,有一个未知类由 ?
表示并且必须 extend Number
最重要的是方法 useMe1
,例如,它必须是 V
的父类(super class)其中 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
无关, 和 ?
在这种情况下 MyNumber
. MyNumber
受 A
限制类型参数绑定(bind)到 extends Number
并根据 useMe2
中参数的类型参数定义扩展FooInterface
但是V
本身是完全不受限制的。