I have been playing with generics and variance. I have two lists one without generics and with generics defined like below:
List l1 = new ArrayList<Integer>();
List<Object> l2 = new ArrayList<Integer>();
The compiler works fine for first. But for the second one, it raises the following error:
Error:(12, 31) java: incompatible types: java.util.ArrayList<java.lang.Integer> cannot be converted to java.util.List<java.lang.Object>
Now, from my understanding List
without generics is a List<Object>
as it allows all types of objects. If both are same, why does compiler have to raise an error?
Can anyone please explain the difference in detail?
EDIT Okay, from the linked duplicate, I was able to learn about Raw Types. But
from
Just what is the difference between the raw type List and the parameterized type List? Loosely speaking, the former has opted out generic type checking, while the latter explicitly told the compiler that it is capable of holding objects of any type. While you can pass a List to a parameter of type List, you can't pass it to a parameter of type List. There are subtyping rules for generics, and List is a subtype of the raw type List, but not of the parameterized type List. As a consequence, you lose type safety if you use raw type like List, but not if you use a parameterized type like List.
this part :
As a consequence, you lose type safety if you use raw type like List, but not if you use a parameterized type like List.
Didn't understand above. How is the List<Object>
more type-safe than List
if all types extend java.lang.Object
? Just because of the sub typing rules?