问题
Consider this case:
class A {}
class B<T extends A, E extends T> {
B<?, A> b;
B<?, ? extends A> b2;
}
As I understand type bounds, in this case effective upper bounds of both T
and E
is class A
. So the question: why javac doesn't accept class A as argument in declaration of field b
, but accepts wildcard
? extends A
in declaration of field b2
?
回答1:
With the following classes:
class A {}
class C extends A {}
class B<T extends A, E extends T> {}
Think of it like this:
E extends T extends A
With B<?,A>
then T -> ?
and E -> A
A extends ? extends A
Where the ?
could be any subclass of A
, let's say C
.A extends C extends A
is clearly invalid.
So that's why it's a compile error.
Note for Eclipse users:
Eclipse 4.9.0 compiler disagreed with javac 8u and Intellij and did not emit a compile error for the generic arguments in B<?,A>
. I assume this is a bug in the Eclipse compiler but I have not consulted the JLS to confirm this.
class B<T extends A, E extends T> {
B<?, A> b; // <-- Eclipse does NOT emit a compile error
B<?, ? extends A> b2;
}
This assumed bug has been reported here.
回答2:
Your declaration is incorrect. You are missing the point of 'wildcard'-s. They are used for unknown property declaration. For B<?, E> b
the E
must extend the T
and the T
must extend the A
but you said that the first generic type is ?
which is unknown! So you said that an unknown parameter must be extend T
and so A
. It is incorrect.
Relationship you created is like E -> T -> A
. After that you declared as a 1. generic type ? -> E -> T -> A
and 2. generic type as A -> E -> T -> ?
. So ? must extends ? and A must extends E vs.. It is confusing and unknown for compiler...
回答3:
In your declaration of field b
, type T
can be anything that extends A
. In turn E
must extend T
however you are supplying type A
for T
. A
will not be a subclass of something that is the subclass of A
.
来源:https://stackoverflow.com/questions/53959451/wildcard-and-type-pameter-bounds-in-java