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

标签 java generics scjp ocpjp

<分区>

准备 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在上面打电话,VFooInterface这与 Number 无关, 和 ?在这种情况下 MyNumber . MyNumberA 限制类型参数绑定(bind)到 extends Number并根据 useMe2 中参数的类型参数定义扩展FooInterface但是V本身是完全不受限制的。

关于Java 泛型类型参数不在其范围内,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45673788/

相关文章:

java - 比较不同对象的 2 个 Java 数组列表,并将匹配的行添加到新列表中

java - Quartz 调度程序、XML ValidationException

c# - 用于类型推断的通用身份函数

java - 枚举示例说明

java - 计算符合 GC 条件的对象数量

java - 如何在 java 中将 boolean 对象类型设置为表列

Java JMenuItem 在第二个menuItem之后添加边框

C# 无法从泛型方法调用重载的非泛型方法

java - 如何获取通用列表实例的特定项目

java - 为什么不能将两个字节加一个整数并可以将两个最后字节加一个字节?