Na jednym z listningów w książce Java. Kompedium Programisty. jest takie coś:
/*
Poniższego kodu nie można skompilować,
ponieważ informacje na temat
typu sparametryzowanego nie istnieją
w trakcie pracy programu
*/
// if(iOb2 instanceof Gen2<Integer>)
// System.out.println("iOb2 to egzemplarz Gen2<Integer>");
Myślę, że to jest odpowiedź na Twoje pytanie, dlaczego to nie działa. Java kompilując kod generyczny robi tam normalne rzutowania z Object na jakiś konkretny typ:
Kod napisany przez programistę:
class Foo<T> {
T obj;
public Foo(T obj) {
this.obj = obj;
}
public T getObj() {
return obj;
}
}
// uzycie
Foo<String> fooString = new Foo<>("Hello");
String obj = fooString.getObj();
Po kompilacji kod klasy Foo<T> będzie prawdopodobnie taki:
class Foo {
Object obj;
public Foo(Object obj) {
this.obj = obj;
}
public Object getObj() {
return obj;
}
}
//tam gdzie bedzie uzycie:
Foo fooString = new Foo("Hello");
String str = (String) fooString.getObj();
Mówiąc jeszcze inaczej typy generyczne dla JVM nie istnieją. One są tylko elementem języka Java. A język Java i JVM to dwie różne rzeczy (mimo że w JVM J to Java). Weź pod uwagę fakt, że np. język Kotlin jest kompilowany do tego samego co Java -> czyli do bytecode.
Dodatkowo we wspomnianej książce Twój konkretny przypadek jest opisany tak:
Próba użycia parametru typu T do utworzenia obiektu spowoduje zgłoszenie błędu. Powód
takiego ograniczenia łatwo zrozumieć: kompilator nie wie, jakiego typu obiekt należy utworzyć.
T jest jedynie nazwą zastępczą.
Czyli to co wyjaśnia komentarz w pierwszym listningu.