Ważną cechą typów parametrycznych jest możliwość pisania algorytmów polimorficznych, czyli algorytmów, które operują na strukturze danych niezależnie od wartości jej parametru, np Arrays.sort()
.
W przypadku typów ogólnych odbywa się to za pomocą typów symboli wieloznacznych:
<E extends Comparable<E>> void sort(E[]);
Aby były naprawdę użyteczne, typy symboli wieloznacznych wymagają przechwytywania symboli wieloznacznych, a to wymaga pojęcia parametru typu. Żadna z tych opcji nie była dostępna w czasie dodawania tablic do języka Java, a tworzenie tablic o kowariantach typu referencyjnego pozwoliło na znacznie prostszy sposób dopuszczenia algorytmów polimorficznych:
void sort(Comparable[]);
Jednak ta prostota otworzyła lukę w systemie typów statycznych:
String[] strings = {"hello"};
Object[] objects = strings;
objects[0] = 1; // throws ArrayStoreException
wymagające sprawdzenia w czasie wykonywania każdego dostępu do zapisu w tablicy typu referencyjnego.
Krótko mówiąc, nowsze podejście zawarte w rodzajach generycznych sprawia, że system typów jest bardziej złożony, ale także statycznie bezpieczniejszy dla typów, podczas gdy starsze podejście było prostsze i mniej statycznie bezpieczne. Projektanci języka zdecydowali się na prostsze podejście, mając do zrobienia ważniejsze rzeczy niż zamknięcie małej luki w systemie czcionek, która rzadko powoduje problemy. Później, kiedy powstała Java i zadbano o pilne potrzeby, mieli zasoby, aby zrobić to dobrze dla generycznych (ale zmiana dla tablic zepsułaby istniejące programy Java).