Bruce Eckel has some further thoughts about the use of erasure in Java generics.
Erasure is the way that Java gets generic types without adding VM support. When the developer writes something like:
in Java generics, the compiler knows that this type can only contain an integer, but when the bytecodes are generated, the type is really:
This means that Java generics doesn't give you the performance benefit that .NET generics do - not only do you not have the ability to create generics on value types (not that surprising given that Java has previously not had boxing), but you still have typecasts in your generated code.
Advantages? Well, the advantage I always heard was that erasure meant that you could run on downlevel VMs, but it turns out that that isn't true. It does mean that it's much easier to write a 5.0 VM than it would be if an approach such as the .NET one was used.
The other advantage is that because the underlying object is really a List<Object>, it's possible to implement a wildcard feature in which you can write something like (and forgive me if my Java syntax is wrong):
which means a List of anything. You can get away with this in erasure because everything's the same type under the covers, but it would be much more challenging in the .NET implementation because List<double> is very different than List<string>.
My personal opinion is that it's far more important to be able to have generics over value types and performant implementations than to support wildcards. In VS2003/C# V1.1, programmers sometimes need to ask the following question:
"Hmm, I need a list of integers here. Should I use an ArrayList, which is easy to write, or should I use my own IntegerList class, which is a bit harder to write, but performs better. Or should I use an array".
The fact that users need to consider that is bad, as is the fact that code contains all three options, and it's often hard to know why a specific option was chosen.