为OCPJP 6考试做准备(这就是我使用Java1.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编译器)时,会得到以下错误:
类型参数V不在其界限之内
尽管上面的代码是不可用的,但我想知道为什么编译器认为<? super V>和<? extends V>类型匹配类类型绑定,而<V>不匹配(因为V匹配这两个边界)。
我不打算修改那个代码,我想要理解它。代码摘自OCPJP 6考试试题“哪一行将编译?”
发布于 2017-08-14 16:41:52
第三个是useMe3,它失败了,因为V不能保证它的声明<V>不受限制。而且,由于参数声明为A<V>,因此没有任何场景,所以V必须扩展Number,并且在这种情况下,Java语言要求程序员显式地声明这一点。
事实上,这是容易的,也许不太明显,为什么其他两个可能会起作用。通过在他们的参数类型定义中使用?,您将给出与extend Number兼容的机会,即使V本身是一个priory,而不受与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是与Number无关的FooInterface,在本例中是与MyNumber无关的?。MyNumber受到绑定为扩展Number的A类型参数的限制,受useMe2中参数的类型参数定义的限制以扩展FooInterface,但V本身是完全不受限制的。
https://stackoverflow.com/questions/45673788
复制相似问题