考虑这种情况:
class A {}
class B<T extends A, E extends T> {
B<?, A> b;
B<?, ? extends A> b2;
}
据我了解类型边界,在这种情况下,T
和E
的有效上限均为class A
。那么问题来了:为什么javac在字段b
的声明中不接受A类作为参数,而在字段wildcard
的声明中接受? extends A
b2
?
答案 0 :(得分:1)
您的声明不正确。您错过了“通配符”的含义。它们用于未知属性声明。对于B<?, E> b
,E
必须扩展T
,而T
必须扩展A
,但是您说的第一个通用类型是?
未知!因此,您说过,未知参数必须扩展T
,依此类推A
。不正确
您创建的关系就像E -> T -> A
。之后,您声明为1.泛型类型? -> E -> T -> A
和2.泛型为A -> E -> T -> ?
。那呢必须延伸?和A必须扩展E与。对编译器而言,这是令人困惑且未知的...
答案 1 :(得分:1)
具有以下类别:
class A {}
class C extends A {}
class B<T extends A, E extends T> {}
这样想:
E extends T extends A
使用B<?,A>
然后使用T -> ?
和E -> A
A extends ? extends A
?
可以是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;
}
已假设here报告了此假定的错误。
答案 2 :(得分:0)
在字段b
的声明中,键入T
可以是扩展A
的任何内容。反过来,E
必须扩展T
,但是您要为A
提供类型T
。 A
不会是A
的子类。