Java получает вторые общие типы

#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