Представьте, что у вас есть абстрактный суперкласс, который является общим:
public abstract class Foo<? extends T> {}
И затем у вас есть второй класс, который расширяет Foo универсальным Bar, расширяющим T:
public class Second extends Foo<Bar> {}
Вы можете получить класс Bar.class
в классе Foo, выбрав Type
(из ответа Берта Бруйнооха) и выведя его, используя Class
экземпляр:
Type mySuperclass = myFoo.getClass().getGenericSuperclass();
Type tType = ((ParameterizedType)mySuperclass).getActualTypeArguments()[0];
//Parse it as String
String className = tType.toString().split(" ")[1];
Class clazz = Class.forName(className);
Следует заметить, что эта операция не идеальна, поэтому рекомендуется кэшировать вычисленное значение, чтобы избежать многократных вычислений. Одно из типичных применений - это общая реализация DAO.
Окончательная реализация:
public abstract class Foo<T> {
private Class<T> inferedClass;
public Class<T> getGenericClass(){
if(inferedClass == null){
Type mySuperclass = getClass().getGenericSuperclass();
Type tType = ((ParameterizedType)mySuperclass).getActualTypeArguments()[0];
String className = tType.toString().split(" ")[1];
inferedClass = Class.forName(className);
}
return inferedClass;
}
}
Возвращаемое значение - Bar.class при вызове из класса Foo в другой функции или из класса Bar.