I'm no Java super-expert, so I'm not completely sure about what I will state. Here are my thoughts:
As Java implements generics by erasure, for every generic type there is an underlying raw type. If you define a generic type, there will be an underlying raw type that will use Object
all around.
When you instantiate a new ArrayList
, it would be wrong for compiler to infer the type parameter from the instantiation class (ArrayList<String>
in your example), as there is a class with that exact name and no type parameter (that is the raw type, ArrayList
). I also guess that this is why in java 7 you will have to add <>
to the constructor call to tell the compiler to infer the type.
One could argue that the compiler should instantiate the raw type only when the definition class is the raw type, but I think that it would be confusing. I think that the compiler have to infer from incomplete expressions that would be invalid with no given context, which is not the case for the new ArrayList()
statement.
I hope this is clear, and that if I'm wrong someone can correct me.
Side note:
Also, beware that the raw class is not the same as the type using Object
as type parameter:
List<String> list = new ArrayList();
is valid, where as
List<String> list = new ArrayList<Object>();
is not. In the first case, the raw type can be used as if it was a generic type, but in the second case you ask for contravariance which is not available (not if you don't use wildcards).