#java #generics #reflection #parameterized-types
#java #дженерики #отражение #параметризованные типы
Вопрос:
Я изо всех сил пытаюсь получить тип второго общего из объекта.
Абстрактный класс принимает два общих типа T и S
abstract class Concept<T, S> {
public Concept() {
//do nothing
}
public final Class<?> getTypeParam() {
ParameterizedType parameterizedType = (ParameterizedType) getClass().getGenericSuperclass();
Class<?> result = (Class<?>) parameterizedType.getActualTypeArguments()[0];
return resu<
}
}
В этом производном классе определен один (в данном случае T) универсальный:
public class Decision<S> extends Concept<String, S>{
public Decision () {
super();
System.out.println(getTypeParam()); //returns the first parameterized type. How do I get the second one?
}
}
Когда я теперь запускаю его, я получаю первый разделенный общий обратно. Отлично. Но как мне получить второй?
public class Main {
public static void main(String[] args){
Decision<Boolean> myBooleanDecision = new Decision<>();
}
}
Комментарии:
1.
(Class<?>) parameterizedType.getActualTypeArguments()[1];
?2. Никогда не помещайте такую информацию в комментарии . Вместо этого всегда обновляйте свой вопрос . Никто здесь не хочет расшифровывать трассировки стека из комментариев…
3. И обратите внимание: это исключение генерируется в классе Decision. Этот класс имеет только 1 общий параметр, поэтому вы не можете запрашивать второй . Вы должны переработать свой метод, чтобы, например, возвращать СПИСОК классов, а затем возвращать список.
4. Наконец: понимание того, как работать с массивами, — это базовая java. Проверка общих типов… это очень продвинутый материал. Кажется, у вас проблемы с базовыми материалами… поэтому я серьезно рекомендую: на некоторое время забыл о продвинутых вещах. Сначала изучите основы. Если вы не понимаете, почему ваш код выдает это исключение, то эти расширенные разделы для вас не подойдут.
5. @GhostCat: Я думаю, что ваш второй комментарий здесь квалифицируется как ответ. В нем описывается проблема и предлагается решение…
Ответ №1:
Ваша проблема основана на том факте, что вы не понимаете своих требований.
Ваша сигнатура метода выглядит следующим образом: public final Class<?> getTypeParam()
Но что вы упускаете из виду: количество параметров типа в ваших классах не является фиксированным. Базовый класс Concept допускает два параметра типа, но подкласс Decision «исправляет» первый параметр в строку.
Таким образом: вы должны решить, чего вы на самом деле хотите / нуждаетесь. Существуют различные решения, такие как:
public final Class<?> getFirstParam()
… чтобы вернуть индекс 0, всегдаpublic final Class<?> getSecondParam()
… чтобы всегда возвращать индекс 1 (что, очевидно, не работает для классов, которые имеют только 1 параметр общего типа)public final List<Class<?>> getParams()
… чтобы вернуть список со всеми записями
Это ваше пространство опций. Какое решение выбрать, зависит исключительно от назначения этого метода (о котором мы ничего не знаем).
Лично я бы выбрал третий вариант, поскольку он будет работать для параметров типа 0, 1, … n без каких-либо изменений.
Ответ №2:
Измените объявление:
Decision<Boolean> myBooleanDecision = new Decision<>("Binary Decision") {};
Теперь это приведет ко второму общему:
Class<?> result = (Class<?>) parameterizedType.getActualTypeArguments()[0];
Вывод:
class java.lang.Boolean