为什么以下代码无法编译?这个例子可以简化(更少的类)来证明等效错误吗?
产生的错误信息是:
在...中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
}
答案 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.
}