【问题标题】:Java generic type parameter not within its bound [duplicate]Java泛型类型参数不在其范围内[重复]
【发布时间】:2018-01-22 05:58:47
【问题描述】:

准备 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 不在其范围内

尽管上面的代码无法使用,但我想知道为什么编译器认为 &lt;? super V&gt;&lt;? extends V&gt; 类型与绑定的类类型匹配,但 &lt;V&gt; 不匹配(因为 V 匹配这两个边界)。

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

【问题讨论】:

  • useMe2 不能与 Java 8 一起编译。
  • 第二个也不编译:/

标签: java generics scjp ocpjp


【解决方案1】:

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

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

您必须注意到extend Number 不再影响V,但? 不管那是什么。另一种说法是,有一个未知的类,它由 ? 表示,并且必须是 extend Number,在此之上是方法 useMe1,例如,它必须是 V 的超类,其中 @987654339 @ 将由调用该方法的代码确定。

这在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,在这种情况下?MyNumberMyNumber 受限于 A 类型参数绑定到扩展 NumberuseMe2 中参数的类型参数定义扩展 FooInterfaceV 本身是完全不受限制的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-24
    • 1970-01-01
    • 2021-07-17
    • 2012-04-15
    • 1970-01-01
    • 2019-03-25
    • 1970-01-01
    相关资源
    最近更新 更多