Ich denke auch, daß Generics und Templates prinzipiell dem gleichen Zweck dienen. In C++ wurde sie halt als Feature des Präprozessors implementiert, so daß jede "Instanziierung" des Templates intern neuen Quelltext und daraus resultierend eigenen Binärcode erzeugt. In Java wird gemeinsam genutzter Bytecode erzeugt, der im Prinzip nur das Casting automatisch übernimmt. Damit stehen sich bei der Implementierung zwei Ideologien konträr gegenüber: maximale Geschindigkeit gegen minimale Codegröße und Abwärtskompatibilität.
Soweit ich die Implementierung von Generics verstanden habe, war allerdings das Bemühen um Abwärtskompatibilität zu Lasten der Laufzeit eine reichlich sinnlose Aktion, weil 1.5er-Programme wegen geänderter Klassenbilbiotheken in aller Regel ohnehin nicht auf einer 1.4er VM laufen.
Als alter C-Programmierer, der es Jahre (beinahe schon Jahrzehnte) gewohnt ist, das Letzte an Performance rauszquetschen, fand ich es schon ein bißchen enttäuschend, daß man bei den Generics darauf verzichtet hat, sie - dort wo es möglich ist - laufzeitoptimal zu implementieren. Das Argument Codegröße ist in C++ eigentlich auch sekundär, weil man ja in der Praxis keine 100 verschiedenen Instanzen eines Templates benutzt.
Auf der anderen Seite ist Java halt nun mal nicht primär auf Performance ausgerichtet. Wer sich schon mal in die Tiefen von Methoden wie setRGB begeben hat, weiß was ich meine. Dafür ist es ein schönes Gefühl zu wissen, daß die Programme - von unrühmlichen Ausnahmen abgesehen - unverändert auf sehr unterschiedlichen System laufen, solange die eine J2SE haben.