Yes, well actually I've read this topic the other day quite thoroughly, as well as the explanation
that we were directed to
here
and actually recalled a long discussion about this subject in our favourite KS && BB guide.
Well to keep things short....
They raise there the question and ask why this kind of usage is allowed with arrays, meaning we can build an array
using a reference type of a super class and the actual object of its subtype as follows:
Code: Select all
Animal [ ] animals = new Dog[ 3 ] ;
and it is perfectly legal and compiles just fine, not to mention that a method can accept an array of Animals by its definition and take an array of one of its subtypes while running, and add to it a Dog object for instance.. and this is also perfectly legal,
So why doesn't it work with collections the same way?
why can't we just send a collection of Dogs to a method that takes Animals and its subtypes?
and the answer they give there is that the compiler can never know what kind of elements you might add to the collection that was sent to a method that takes a collection of Animals and its subtypes.
For instance lets say that we send a collection of Dogs to a method that takes a collection of Animals and its subtypes,
nothing can prevent us from adding a Cat to this collection of Dogs :
public void addAnimal(List<? extends Animal> animals){
animals.add(new Cat()) ; // Here we try to add a Cat element to a collection
// that might be a collection of only Dogs
}
And now back to the question why should it defer from the behaviour of arrays?
here they say that it is different with arrays since there is a special exception that can be thrown at runtime
(ArrayStoreException), while with generic collections we still have the compiler's type- erasure process that actually
cause a collection that was defined in a generic fashion to be seen by the compiler as it was declared in the legacy old fashioned way (that creates a collection of objects that we should use casting when trying to retrieve an element from it) .
The compiler use the type- erasure process for compatibility reasons with old codes (pre java 5...)
so that at runtime no exception can be thrown in case of adding a collection of one type an element of a wrong type.
I hope i got it right, was that true || false?