The following should compile but does not. Appeared in the paper "Taming Wildcards in Java's Type System," Ross Tate et al., PLDI 2011.
import java.util.*;
public class TateFigure5 {
class C<P extends Number> extends ArrayList<P> {}
List<? extends List<? extends Number>> cast(List<C<?>> list)
{return list;}
}
The subtyping derivation is straightforward:
List<C<?>> <: List<? extends List<? extends Number>>
C<?> <: List<? extends Number>
List<CAP extends Number> <: List<? extends Number>
CAP extends Number <: Number
true
Interestingly, if C is an interface that extends List rather than a class that extends ArrayList, compilation succeeds.
This is longstanding behavior, probably due to the way javac handles wildcards in subtyping. Not a regression.