构造函数的一般限制

时间:2011-07-09 17:32:11

标签: java generics

为什么以下代码无法编译的任何想法?

public class A<TT extends B<?>> extends C<TT> implements D<TT> {

    protected A(Class<TT> c) {
        super(c);
    }

}

interface B<MM> {

}

interface D<MM extends B<?>> {

}

abstract class C<TT> {
    protected C(Class<TT> c) {

    }
}

class F implements B<String> {

}

class G extends F {

}

class E<TT extends B<String>> {
    public E() {
        // why does this not work?
        // Error: The constructor A<TT>(Class<G>) is undefined
        D<TT> d = new A<TT>(G.class);

    }
}

3 个答案:

答案 0 :(得分:1)

您需要指定一个实际的类来替换TT:

new A<G>(G.class);

编译器应该能够推断出类型,甚至没有明确说明它:

new A(G.class);

答案 1 :(得分:1)

简单:G.classClass<G> - 而不是Class<TT>

这有效:

D<G> d = new A<G>(G.class);

...但您不知道TT的类型(在E中),因此您无法向Class<TT>构造函数提供相关的A<TT>实例。这也会编译,但可能不是你想要的:

// Oops - we don't really have TT.class, and can't refer to it...
D<TT> d = new A<TT>(null); 

想象一下,我们尝试使用您当前的代码,并且:

class H extends B<String> {}

然后构造一个E<H>是完全合理的,但是你试图将G.class传递给A<H>的构造函数 - 它显然不是同一类型。

(作为旁注,使这些示例尽可能简单是非常有帮助的。这意味着要删除所有不相关的类,并且为了清楚起见避免重用类型参数名称。)< / p>

答案 2 :(得分:0)

我认为问题是构造函数参数不匹配:G.class不是String.class(TT)。