I read a tweet today that said:
It\'s funny when Java users complain about type erasure, which is the only thing Java got right, while ignoring all th
The reason type erasure is a good thing is that the things it makes impossible are harmful. Preventing the inspection of type arguments at runtime makes understanding and reasoning about programs easier.
An observation that I found somewhat counter-intuitive is that when function signatures are more generic, they become easier to understand. This is because the number of possible implementations is reduced. Consider a method with this signature, which we somehow know has no side effects:
public List XXX(final List l);
What are the possible implementations of this function? Very many. You can tell very little about what this function does. It could be reversing the input list. It could be pairing ints together, summing them and returning a list half the size. There are many other possibilities that could be imagined. Now consider:
public List XXX(final List l);
How many implementations of this function are there? Since the implementation cannot know the type of the elements, a huge number of implementations can now be excluded: elements cannot be combined, or added to the list or filtered out, et al. We are limited to things like: identity (no change to the list), dropping elements, or reversing the list. This function is easier to reason about based on its signature alone.
Except… in Java you can always cheat the type system. Because the implementation of that generic method can use stuff like instanceof checks and/or casts to arbitrary types, our reasoning based on the type signature can be easily rendered useless. The function could inspect the type of the elements and do any number of things based on the result. If these runtime hacks are allowed, parameterised method signatures become much less useful to us.
If Java did not have type erasure (that is, type arguments were reified at runtime) then this would simply allow more reasoning-impairing shenanigans of this kind. In the above example, the implementation can only violate the expectations set by the type signature if the list has at least one element; but if T was reified, it could do so even if the list were empty. Reified types would just increase the (already very many) possibilities for impeding our understanding of the code.
Type erasure makes the language less "powerful". But some forms of "power" are actually harmful.