6

考虑这种情况:

class A {}

class B<T extends A, E extends T> {
    B<?, A> b;
    B<?, ? extends A> b2;
}

据我了解类型界限,在这种情况下,两者的有效上限TEis class A。所以问题是:为什么 javac 在声明字段时不接受类 A 作为参数b,但wildcard ? extends A在声明字段时接受b2

4

3 回答 3

1

您的声明不正确。你错过了'通配符'-s的意义。它们用于未知属性声明。对于必须扩展B<?, E> b和必须扩展,但您说第一个泛型类型是未知的!所以你说一个未知的参数必须是 extend等等。这是不正确的。 ETTA?TA

您创建的关系就像E -> T -> A. 之后,您将 1. 泛型类型? -> E -> T -> A和 2. 泛型类型声明为A -> E -> T -> ?. 所以 ?必须扩展?并且 A 必须扩展 E vs.。这对于编译器来说是令人困惑和未知的......

于 2018-12-28T14:33:12.777 回答
1

有以下课程:

class A {}
class C extends A {}
class B<T extends A, E extends T> {}

可以这样想:

E extends T extends A
假设B<?,A>thenT -> ?E -> A
A extends ? extends A
Where?可以是 的任何子AC
A extends C extends A显然是无效的。
所以这就是为什么它是一个编译错误。


Eclipse 用户注意事项:

Eclipse 4.9.0 编译器不同意 javac 8u 和 Intellij 并且没有为B<?,A>. 我认为这是 Eclipse 编译器中的一个错误,但我没有咨询 JLS 来确认这一点。

class B<T extends A, E extends T> {
    B<?, A> b; // <-- Eclipse does NOT emit a compile error
    B<?, ? extends A> b2;
}

这个假定的错误已在此处报告。

于 2018-12-28T14:37:39.300 回答
0

在您的字段声明中b,类型T可以是任何可以扩展的内容A。反过来E必须扩展T,但是您提供的类型AT. A不会是 的子类的子类A

于 2018-12-28T14:44:51.733 回答