Java泛型:使用捕获编译失败

时间:2013-05-10 14:48:27

标签: java generics compiler-errors capture

为什么以下代码无法编译?这个例子可以简化(更少的类)来证明等效错误吗?

产生的错误信息是:

在...中

func(捕获?延伸A)无法应用于B

    private static interface A {}
    private static class B implements A {}

    private static class C<T> {
        private final T t;
        private C(T t) {
            this.t = t;
        }
        private void func(T t) {}
    }

    @Test
    public void doTest() {
        B b = new B();
        C<? extends A> c = new C<B>(b);
        c.func(b); // fails here
    }

2 个答案:

答案 0 :(得分:5)

问题是,C<? extends A>表示“对于某些类型C<T>来说它是T,但我不知道它是哪种类型 - 只是它扩展了{{1} }}“。

这意味着无法假设A,或者T = B转换为B。但这正是你试图在这里假设的:

T

为了证明它无效的原因,假设我们对您的代码进行了更改:

c.func(b);

现在更明显的是它不应该编译 - 如果你有一个private static class X implements A {} B b = new B(); C<? extends A> c = new C<X>(new X()); c.func(b); ,你不希望能够C<X> func(b) b { {1}},你呢?因此,鉴于我更改了赋值的右侧(而不是B的声明类型),对于您的示例进行编译会非常奇怪,但我不会这样做。这有帮助吗?

与以往一样,请参阅Java Generics FAQ以获取更多信息,尤其是关于wildcards的部分。

答案 1 :(得分:3)

该行必须失败,否则这个明显错误的代码可以编译:

private static interface A {}
private static class B implements A {}
private static class B2 implements A {}

@Test
public void doTest() {
    B b = new B();
    B2 b2 = new B2();
    C<? extends A> c = new C<B2>(b2); // B2 extends A, ok.
    c.func(b); // B extends A, but B is not B2, and it should fail.
}