Reputation: 2422
class P {
}
class Q extends P {
}
class R extends Q {
}
class S extends R {
}
public class Manager {
public static void main(String[] args) {
X<? super R> x4 = null;
x4.test(new S());
x4.test(new R());
x4.test(new P());//compile time error
}
}
class X<A> {
void test(A obj) {
}
}
//means that R or superclass of R i.e P, Q or Object but then why I get a compile time error on line as specified in the program.
Upvotes: 2
Views: 132
Reputation: 280181
Here are some rules from the JLS
A type argument
T1
is said to contain another type argumentT2
, writtenT2 <= T1
, if the set of types denoted byT2
is provably a subset of the set of types denoted byT1
under the reflexive and transitive closure of the following rules (where<:
denotes subtyping (§4.10)):
? super T <= ? super S if S <: T
? super T <= ?
? super T <= ? extends Object
T <= ? super T
The notation
X<? super R> x4 = null;
declares X
with a generic wildcard type argument that has a lower bound of R
.
With the rules above and your declaration of the variable, we can determine that the wildcard covers any sub types of R
and R
itself. S
is a sub type of R
, R
is R
, P
is not a sub type of R
.
The confusion may come in the following. You can do
X<? super R> x4 = new X<P>();
since P
is a superclass of R
. However, when you want to use the type parameter of the class X
, all you know is that it must at least be an R
.
Further reading:
Upvotes: 4
Reputation: 1083
You can pass objects extending R, i.e. R or S, but not parents of it. R is the super class of any passed instance!
Upvotes: 0