So what are generics in Java exactly? As mentioned by dave, the generic types are compiler enforcements. To be exact, at runtime, the generic types do not exist anymore. They are replaced by Object
or the upper bound of a generic type. This process is called Type Erasure. So, generic types only exist at compile-time.
Then why can we not cast an ArrayList<String>
into an ArrayList<Object>
? Even though the type parameters stand in a relation (String
is a Object
), the generic classes do not. Let me give a simple example. If
ArrayList<String> strings = new ArrayList<String>();
ArrayList<Object> objects = strings;
would be possible, if one calls
objects.add(new Object());
what should happen? Since strings
can only hold String
s, Java cannot "put" an Object
into this list. But on the other hand, if you look at the declaration of objects
there is nothing hinting, that this should not work. Therefore, Java does not allow conversion between generic classes, even if the generic types stand in a relation.
But generic types are not present at runtime. So what is the hustle? Should ArrayList<String>
not really be an ArrayList<Object>
at runtime and therefore, all of this should not matter? Well no. Since you know the type at compile-time, you can use certain contracts. For example, when retreiving an element out of an ArrayList<String>
one can be sure that this retrieved object has the public char charAt(int)
method (since a String
has this method). If, for whatever reason, this ArrayList<String>
would return an Object
instead of a String
, one could not call the charAt(int)
method.