Suppose a SuperClass America and two of its SubClasses SouthAmerica and NorthAmerica
Case 1
For Arrays:
America[] am = new SouthAmerica[10]; //why no compiler error
am[0]= new NorthAmerica(); //ArrayStoreException at RunTime
Case 2
While in Genrics:
ArrayList<America> ame = new ArrayList<SouthAmerica>(); //this does not compile
My question is not why case 2 does not compile but my question is why case 1 compiles.I mean what else can be do this base Array Type and Sub Array Object??
That's because arrays are covariant.
That behavior for arrays is largely considered a mistake:
Generic collections - being newer, fixed that mistake.
You can use bounded wildcard notation
<? super America>
:This will allow you to add items to the list, but it will avoid the problematic behavior.
See this official tutorial on how to use them.
You are doing something wrong. Based on what you described, suppose we have the following
I try to compile the above class and it errors out.
Case 1: I assume you meant:
It's valid for am to hold an array of SouthAmerica as SouthAmerica extends America.
The second line is NOT valid since the array is of SouthAmerica and you're trying to set a NorthAmerica. SouthAmerica is NOT a superclass of NorthAmerica.
The point of the first being valid is that later you can validly say:
This is all due to the covariance property of arrays.
Case 2: While SouthAmerica does extend America, that does not work through generics. ArrayList does NOT extend ArrayList as the implication does not hold. Generics(even though in this case it's an ArrayList) does not act in the same way as a full array.
Because arrays are covariant and collections are contravariant. This means that
Stirng[]
isObject[]
, butList<String>
is notList<Object>
. You should write the following instead: