I generici reificati non richiedono il supporto JVM. Sì, sarebbero più facili e più performanti con il supporto JVM, ma il supporto JVM non è necessario. Ad esempio, un compilatore Scala potrebbe, per ogni classe che presenta una variabile di tipo, aggiungere un campo che memorizza l'oggetto corrispondente:
class List<T> {
}
void test() {
List<?> list = new List<String>();
List<Integer> intList = (List<Integer>) list;
}
sarebbe compilato per
class List<T> {
final Class<T> tClass;
public List(Class<T> tClass) {
this.tClass = tClass;
}
public <O> List<O> castTo(Class<O> oClass) {
if (tClass == oClass) {
return (List<O>) this;
} else {
throw new ClassCastException("Incompatible type parameter: " + tClass);
}
}
}
void test() {
List<?> list = new List<String>(String.class);
List<Integer> intList = list.castTo(Integer.class);
}
Esistono ovviamente strategie di traduzione più elaborate che si integrano più facilmente con il sistema di tipi di host, ad esempio avendo effettivamente classi separate per argomenti di tipo diverso con lo stesso tipo generico:
class List<T> {
}
class List#Integer extends List<Integer> { }
class List#String extends List<String> { }
void test() {
List<?> list = new List#String();
List<Integer> intList = (List#Integer) list;
}
(Ci sarebbero naturalmente alcune sfide non apparenti in questo banale esempio, ad esempio argomenti di tipo ricorsivo, corretto isolamento di caricatori di classi differenti, ...)
La ragione per cui Java non ha generici reificati non è che la reificazione sarebbe impossibile sulla JVM, ma che i generici reificati avrebbero rotto la compatibilità all'indietro (in particolare la compatibilità binaria) con i programmi Java esistenti - qualcosa di cui Scala non doveva preoccuparsi .