I was reviewing someone else’s code the other day and I came across a line that raised some concern. To simplify, say I have a generic Class A and an abstract Class B. Is the following instantiation allowed and if so, why?
Object obj = new A<? extends B>();
I personally have never seen an instantiation like the above, although a declaration such as
A<? extends B> obj = null;
would certainly hold. I’ve always used the wildcard in generics to declare method parameters, so I may just not have the experience.
Actually
new A<? extends B>()does not compile. It has been consistently illegal since Java 5.But I guess your original example was something like
new A<X<? extends B>>(). The latter is legal in recent versions of Java.The idea is, when instantiating an object, the value for type parameters can be any non-wildcard type.
? extends Bis a wildcard type, so it is disallowed. ButX<? extends B>is not a wildcard type, though it has a wildcard type as a component. So you can say legally callnew A<X<? extends B>>().The rules makes sense if you think about it this way. Ultimately it is a byproduct of the more fundamental rule that a wildcard type like
? extends Bcannot be the declared type of a field or variable. IfAis defined asthen the hypothetical
new A<? extends B>().valuewould be a field declared of type? extends B. Since that is illegal, so is the instantiation. Butnew A<X<? extends B>>()does not have that problem.