3

准备 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 编译器)时,出现错误:

类型参数 V 不在其范围内

尽管上面的代码不可用,但我想知道为什么编译器认为类型<? super V><? extends V>匹配绑定的类类型但<V>不是(因为 V 匹配这两个边界)。

我不打算修改该代码,我想了解它。该代码取自示例 OCPJP 6 考试问题,询问“哪一行将编译?”

4

1 回答 1

1

第三个 ,useMe3失败,因为它的声明没有界限,V所以不能保证。并且由于参数被声明为没有 scape,必须扩展并且 Java 语言要求程序员在这种情况下明确声明。extend Number<V>A<V>VNumber

这实际上是简单的一个,也许其他两个可能起作用的原因不太明显。通过在他们的参数类型定义中使用,即使它本身是一个不受与 相关的任何特定绑定限制的先验?,您也有机会使其绑定兼容。extend NumberVNumber

你必须注意到,extend Number它不再影响V任何东西,但?不管它是什么。换一种说法,有一个未知的类,它由它表示,?并且必须extend Number在它的基础上 for method useMe1,例如,它必须是由调用该方法的代码确定的Vwhere的超类。V

useMe2whereV可以有效地与Number. 例如:

interface FooInterface { ... }
class MyNumber extends Number implements FooInterface { ... }

A<?> subject = ...;
A<MyNumber> param = ...; 
FooInterface foo = subject.useMe2(param);

在上面的useMe2调用中,Vis FooInterfacethat 与 无关,Number?这种情况下, in MyNumberMyNumberA绑定到扩展的类型参数和扩展Number的参数的类型参数定义的限制,但它本身是完全不受限制的。useMe2FooInterfaceV

于 2017-08-14T16:41:52.180 回答