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

时间:2014-11-09 22:07:20

标签: 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已经&#34;延伸&#34; 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>()。 Phew,简单,编译器只是说&#34;应该扩展B,所以B(就像V之前的V一样延伸Error:(6, 16) java: incompatible types required: Carpet<? extends V> found: Carpet<B> &#34 ;)应该是完美的。但!它没有编译:

B

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

  

由于V的确切范围,使用具体类类型是非法的   不明。

但坦率地说,我仍然没有得到它。我不确定&#34;确切的范围&#34;在该上下文中,但编译器说,返回类型参数应该扩展V。所以,他能够弄明白(像我一样)&#34;扩展B&#34;是{&#34;延伸B&#34;的东西。那么,为什么{{1}}不起作用?

请您提供更好的解释?

1 个答案:

答案 0 :(得分:2)

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的具体类型(假设他选择了扩展C的Plane),该方法必须返回一个扩展为V的类型的地毯。因此,在这种情况下,此类型必须是Plane或者Plane的子类型。显然,B不符合条件,因为它不会扩展Plane。