Two days ago I attended a presentation of .NET CLR lead architect
Jim Miller from Microsoft. During his talk he told the story of how generics made their way into .NET 2.0 in great detail. Surprisingly there was an original design goal to keep the bytecode compatible, so that older .NET runtimes would be able to handle generics-comprised code as well. As we all know today, they had to give up that objective. Java 5 on the other hand stayed bytecode-compatible with older versions due to its approach of type erasure - generic classes don't contain type information, so a List
is represented as a List of objects in bytecode. This of course introduces some drawbacks as well, e.g. there is no way to find out the underlying generic type at runtime using reflection (a feature important for RAD tools and others), or the need for casting resp. boxing/unboxing in case of primitive types.
It's interesting to note that in .NET's case, work on generics started as a research project back in 1999, long before the first .NET 1.0 beta had even been published. On the Java frontier, JSR 14 "Adding Generics to the JavaTM Programming Language" was initiated in 1999 as well (actually Java generics are based on the even older project Pizza/GJ). Six years in the making, in both cases. Amazing.
More on generics in Java 5 and .NET 2.0 can be found in this transcript of an interview with Anders Hejlsberg (talking with Bill Venners and Bruce Eckel) and Gilad Bracha's Java generics tutorial.