Java泛型类型参数不在其绑定范围内

时间:2017-08-14 11:44:28

标签: java generics scjp ocpjp

准备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;

1 个答案:

答案 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 VFooInterface无关,Number in ? MyNumber }}。 MyNumber受限于A绑定到扩展Number的类型参数以及useMe2中参数的类型参数定义,以扩展FooInterfaceV 1}}本身完全不受限制。