来自 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/