java - 泛型类型参数边界和具体类

标签 java generics scjp

来自 OCP Java SE 6 程序员练习考试第 49 页,问题 11。我们得到了这样的代码:

class A { }
class B extends A { }
class C extends B { }
public class Carpet<V extends B> {
    public <X extends V> Carpet<? extends V> method(Carpet<? super X> e) {
        // insert code here
    }
}

我们被问到:在标记行处独立插入的哪个会编译?

所以,我正在测试第一个答案 - return new Carpet<X>() 。有用。好吧,如果我的返回类型为 Carpet<? extends V>,我的推理就很好。 ,它必须返回扩展 V 的内容。就在写下之前,X extends V ,那就完美了,X有效。

下一个答案 - return new Carpet<V>() 。嗯,这更简单,因为V已经“扩展”V ,这样我就可以返回它。它有效,好的,很好。

下一个 - return new Carpet<A>() 。这不起作用,编译器大喊:

Type parameter 'A' is not within its bound; should extend 'B'

但是,我同意。它写在类声明附近,V extends B 。所以,我知道我可以返回扩展 V 的东西,延伸B 。肯定不是 A .

所以,我看到下一个答案 - return new Carpet<B>() 。唷,简单,编译器只是说“应该扩展 B ,所以 B (就像之前 V 表示“扩展 V 的东西”)应该是完美的。但是!它没有编译:

Error:(6, 16) java: incompatible types
  required: Carpet<? extends V>
  found:    Carpet<B>

我不明白为什么。书中给出的解释是:

It's illegal to use a concrete class type since the exact scope of V is unknown.

但说实话,我还是不太明白。我不确定该上下文中的“确切范围”意味着什么,但编译器说,返回类型参数应该扩展 B 。所以,他能够(像我一样)弄清楚“延伸V的东西”是“延伸B的东西”。那么,为什么B不起作用?

您能提供更好的解释吗?

最佳答案

V 是地毯的通用类型。实例化 Carpet 时,类的用户选择 V 的具体类型。它可以是 B、C,或直接或间接扩展 B 的任何其他类:

Carpet<B> carpetOfB = new Carpet<B>();

Carpet<C> carpetOfC = new Carpet<C>();

Carpet<Plane> carpetOfPlane = new Carpet<Plane>();

无论用户选择什么作为 V 的具体类型(假设他选择了 Plane,它扩展了 C),该方法必须返回扩展 V 的类型的 Carpet。因此,在这种情况下,该类型必须是 Plane 或 a飞机的子类型。显然,B 不符合条件,因为它没有扩展 Plane。

关于java - 泛型类型参数边界和具体类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26833883/

相关文章:

c - 在c中实现通用堆栈

C# - 代码有什么问题(泛型、静态方法等)

c# - 如何为一个列表中的不同类型的值设计工厂模式?

java - 在接口(interface) : what is the outerclass? 中声明的匿名内部类

java - MyBatis 插入关联

java - 将组件添加到 JPanel 顶部

Java 字符串正则表达式

java - 幸运数字程序未显示正确答案

java - Java 中按位异或的作用是什么?

Java 字符到字节转换