Penso che altre risposte lo abbiano detto in una certa misura, ma non molto chiaramente. Uno dei problemi con i generici sta perdendo i tipi generici durante il processo di riflessione. Quindi per esempio:
List<String> arr = new ArrayList<String>();
assertTrue( ArrayList.class, arr.getClass() );
TypeVarible[] types = arr.getClass().getTypedVariables();
Sfortunatamente, i tipi restituiti non possono dirti che i tipi generici di arr sono String. È una sottile differenza, ma è importante. Poiché arr è creato in fase di runtime, i tipi generici vengono cancellati in fase di esecuzione, quindi non è possibile capirlo. Come alcuni hanno dichiarato che ArrayList<Integer>
è uguale a ArrayList<String>
dal punto di vista della riflessione.
Questo potrebbe non essere importante per l'utente di Generics, ma diciamo che volevamo creare qualche quadro di fantasia che usasse la riflessione per capire cose fantasiose su come l'utente ha dichiarato i tipi generici concreti di un'istanza.
Factory<MySpecialObject> factory = new Factory<MySpecialObject>();
MySpecialObject obj = factory.create();
Diciamo che volevamo un factory generico per creare un'istanza di MySpecialObject
perché questo è il tipo generico concreto che abbiamo dichiarato per questa istanza. Beh, la classe Factory non può interrogarsi per scoprire il tipo concreto dichiarato per questa istanza perché Java li ha cancellati.
Nei generici di .Net è possibile farlo perché in fase di esecuzione l'oggetto sa che sono tipi generici perché il compilatore lo ha eseguito nel binario. Con le cancellature Java non può farlo.