Получение универсального параметра из класса супертипа - PullRequest
3 голосов
/ 30 марта 2012

Скажем, у меня есть родительский интерфейс / класс, подобный этому

interface Parent<T> {}

И ряд реализующих интерфейсов, которые фиксируют универсальный тип.

interface Child extends Parent<Type> {}

Можно ли использовать отражение для полученияэкземпляр Class, представляющий T, если у меня есть объект Class для Child.Примерно так:

<T, I extends Parent<T>> I create(Class<I> type) {
    Class<T> tType = ...
    ...
}

В настоящее время мне нужно передать tType в качестве параметра, но я бы хотел упростить вещи, если смогу.

Ответы [ 3 ]

6 голосов
/ 30 марта 2012

Да, несмотря на то, что говорили другие, эта информация доступна , если у вас есть доступ к объекту подкласса Class.Вам нужно использовать getGenericSuperclass вместе с getActualTypeArguments.

ParameterizedType superClass = (ParameterizedType)childClass.getGenericSuperclass();
System.out.println(superClass.getActualTypeArguments()[0]);

В вашем примере аргумент типа «фактический» должен возвращать Class для Type.

1 голос
/ 29 июня 2017

Если вам нужно сделать что-нибудь нетривиальное с универсальными типами во время выполнения, рассмотрите Guava's TypeToken. Он может ответить на ваш вопрос (и многие другие!) При решении некоторых нюансов, поднятых комментаторами:

private interface Parent<T> {}
private interface Intermediate<U, V> extends Parent<V> {}
private interface Child<Z> extends Comparable<Double>, Intermediate<Z, Iterable<String>> {}

public void exploreGuavaTypeTokens() {
    final TypeToken<? super Child> token = TypeToken.of(Child.class).getSupertype(Parent.class);
    final TypeToken<?> resolved = token.resolveType(Parent.class.getTypeParameters()[0]);
    System.out.println(resolved); // "java.lang.Iterable<java.lang.String>"
    final Class<?> raw = resolved.getRawType();
    System.out.println(raw); // "interface java.lang.Iterable"
}
0 голосов
/ 30 марта 2012

Я так не думаю.Читайте о стирании типов : универсальные типы используются только для проверки во время компиляции, а затем отбрасываются.Они не хранятся в скомпилированных файлах классов, поэтому они недоступны во время выполнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...