考虑这种情况:
class A {}
class B<T extends A, E extends T> {
B<?, A> b;
B<?, ? extends A> b2;
}
据我了解类型界限,在这种情况下,两者的有效上限T
和E
is class A
。所以问题是:为什么 javac 在声明字段时不接受类 A 作为参数b
,但wildcard
? extends A
在声明字段时接受b2
?
考虑这种情况:
class A {}
class B<T extends A, E extends T> {
B<?, A> b;
B<?, ? extends A> b2;
}
据我了解类型界限,在这种情况下,两者的有效上限T
和E
is class A
。所以问题是:为什么 javac 在声明字段时不接受类 A 作为参数b
,但wildcard
? extends A
在声明字段时接受b2
?
您的声明不正确。你错过了'通配符'-s的意义。它们用于未知属性声明。对于必须扩展B<?, E> b
和必须扩展,但您说第一个泛型类型是未知的!所以你说一个未知的参数必须是 extend等等。这是不正确的。 E
T
T
A
?
T
A
您创建的关系就像E -> T -> A
. 之后,您将 1. 泛型类型? -> E -> T -> A
和 2. 泛型类型声明为A -> E -> T -> ?
. 所以 ?必须扩展?并且 A 必须扩展 E vs.。这对于编译器来说是令人困惑和未知的......
有以下课程:
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?
可以是 的任何子A
类C
。
A extends C extends A
显然是无效的。
所以这就是为什么它是一个编译错误。
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;
}
这个假定的错误已在此处报告。
在您的字段声明中b
,类型T
可以是任何可以扩展的内容A
。反过来E
必须扩展T
,但是您提供的类型A
为T
. A
不会是 的子类的子类A
。