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

Leo*_*nid 0 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
    }
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 5

问题是这C<? extends A>意味着"它C<T>适用于某种类型T,但我不知道它是哪种类型 - 只是它是扩展的东西A."

这意味着你不能假设T = B,或者说转换BT.不过,这正是你什么尝试在此假设:

c.func(b);
Run Code Online (Sandbox Code Playgroud)

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

private static class X implements A {}

B b = new B();
C<? extends A> c = new C<X>(new X());
c.func(b);
Run Code Online (Sandbox Code Playgroud)

现在更明显的是它不应该编译 - 如果你有一个C<X>,你不希望能够在func(b)哪里打电话,bB吗?所以考虑到我改变了赋值的右侧(而不是声明的类型c),你的例子编译会很奇怪,但我不会这样做.这有帮助吗?

与以往一样,请参阅Java Generics FAQ以获取更多信息,尤其是有关通配符的部分.