Ответ 1
Вам нужно явно передать класс в конструктор (и сохранить его самостоятельно).
private final Class<T> clazz;
PropertyImplementationBinder(Class<T> clazz){
this.clazz = clazz;
}
public Class<T> getInterfaceClass() {
return clazz;
}
Я пытаюсь связать интерфейс с его реализацией как прочитанный из файла конфигурации, чтобы я мог передать его в мой контейнер IoC. Здесь примерно то, что я пытаюсь сделать:
public class PropertyImplementationBinder<T> {
// ...
public Class getInterfaceClass() {
return T.class; // OR Class<T>, note T is not newable
}
public Class getImplementationClass() {
return /* read config file to get implementation class */;
}
}
Как можно получить T.class
?
Вам нужно явно передать класс в конструктор (и сохранить его самостоятельно).
private final Class<T> clazz;
PropertyImplementationBinder(Class<T> clazz){
this.clazz = clazz;
}
public Class<T> getInterfaceClass() {
return clazz;
}
Вы можете получить фактические аргументы типа для общего суперкласса класса. В этом сообщении сообщается о возможностях, представленных этим, включая хороший небольшой трюк с использованием тривиальных анонимных внутренних классов. Цитировать напрямую:
Оказывается, что, хотя JVM не будет отслеживать фактические аргументы типа для экземпляров универсального класса, он отслеживает фактические аргументы типа для подклассов общих классов. Другими словами, хотя a
new ArrayList<String>()
на самом деле всего лишьnew ArrayList()
во время выполнения, если класс расширяетArrayList<String>
, то JVM знает, чтоString
является фактическим аргументом типа для параметра типаList
.
В отличие от общепринятого и редко известного стирания стилей можно избежать, а это значит, что у вызывающего есть возможность узнать, какие общие параметры использовались во время разговора.
Пожалуйста, взгляните на: Использование TypeTokens для извлечения общих параметров
В статье также рассказывается об опыте наших пользователей с этой техникой. В двух словах, мы закончили тем, что вернулись к...
Обычный и широко используемый метод: "Передать типы классов в конструкторах"
Btw. Пример статического метода getType в статье из @Richard Gomes имеет две ошибки. он должен выглядеть следующим образом:
static public Class<?> getType(final Class<?> klass, final int pos) {
// obtain anonymous, if any, class for 'this' instance
final Type superclass = klass.getGenericSuperclass();
// test if an anonymous class was employed during the call
if ( !(superclass instanceof ParameterizedType) ) {
throw new RuntimeException("This instance should belong to an anonymous class");
}
// obtain RTTI of all generic parameters
final Type[] types = ((ParameterizedType) superclass).getActualTypeArguments();
// test if enough generic parameters were passed
if ( pos >= types.length ) {
throw new RuntimeException(String.format("Could not find generic parameter #%d because only %d parameters were passed", pos, types.length));
}
if (!(types[pos] instanceof Class<?>)) {
throw new RuntimeException("Generic type is not a class but declaration definition(all you get is \"[T]\") " + types[pos]);
}
// return the type descriptor of the requested generic parameter
return (Class<?>) types[pos];
}
К сожалению, это еще не волшебная пуля, потому что она работает, если вы явно в коде
getType(new SomeObject<String>(){}.class, 0) // you get String.class
но если вы назовете это чем-то вроде
getType(new SomeObject<T>(){}.class, 0) // you get T as TypeVariable<D> and not actuall class of it
Просто введите T.
Нет, это невозможно.
Единственное исключение для стирания стилей Java - это то, что через отражение вы можете узнать параметризованный тип через отражение в полях класса.