this is because at runtime, there is no difference between a generics collection and a non-generics collection. (Type erasure)
ArrayList<? extends C> arl is as good as
ArrayList arl at runtime.
if there is no compile time error, then anything can be added to collection at runtime which will break the type safety. So normally you will no be able to assign a ArrayList<C> arl = new ArrayList<A>,
but the wildcards '?' allow you to do the assignment and with extends it can be read only, you can't do structural modifications.
consider the example
Hope this will clear your doubt.
