0

为什么下面的代码编译失败?这个例子可以简化(到更少的类)来演示等效的错误吗?

产生的错误信息是:

func(capture of ? extends A) in ... 不能应用于 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
    }
4

2 回答 2

5

问题是这C<? extends A>意味着“它是C<T>某种类型的T,但我不知道它是哪种类型 - 只是它是扩展的东西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);

现在更明显的是它不应该编译 - 如果你有 a C<X>,你不希望能够调用func(b)where bis a B,是吗?因此,鉴于我更改了赋值的右侧(不是声明的类型c),你的示例编译会很奇怪,但我的不编译。这有帮助吗?

与以往一样,请参阅Java 泛型常见问题解答以获取更多信息,尤其是有关通配符的部分。

于 2013-05-10T14:55:06.933 回答
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.
}
于 2013-05-10T14:55:22.363 回答