The reason for these limitations have to do with variance considerations.
Take the following code:
public void doSomething(List
Expanding your example, you could try to do the following:
List strings = new ArrayList();
string.add("S1");
doSomething(strings);
for (String s : strings)
{
System.out.println(s.length);
}
Hopefully it's obvious why this would break if the compiler allowed this code to be compiled (which it doesn't) - a ClassCastException would occur for the second item in the list when trying to cast the Object to a String.
To be able to pass generalized collection types, you need to do this:
public void doSomething(List> objects)
{
for (Object obj : objects)
{
System.out.println(obj.toString);
}
}
Again, the compiler is watching your back and were you to replace the System.out with objects.add(new Object()) the compiler wouldn't allow this because objects could have been created as List.
For more background on Variance see the Wikipedia artical Covariance and contravariance