Отражение: применение параметров типа объявления класса к полям - PullRequest
0 голосов
/ 01 июня 2019

У меня есть следующая структура классов:

class A<T,R> {
   B<R> b;
......
}

class B<R> {
   R t;
}

class StringConsumer {
   A<String, String> a;
}

class LongConsumer {
   A<Long, Long> a;
}

Учитывая, что у меня есть экземпляр одного из потребительских классов, возможно ли получить параметр (ы) типа для consumer.a.b?Я обнаружил, что могу разрешить то же самое, если объявить a как StringA a;, где class StringA extends A<String, String> с использованием TypeTools

1 Ответ

1 голос
/ 03 июня 2019

Поскольку ваши потребительские классы объявляют поле a без переменных типа, вся необходимая информация о наборе будет присутствовать во время выполнения.

Хотя можно достичь того, что вы просите, используя прямое отражение, оно быстро становится безумным, поэтому я настоятельно рекомендую использовать GenTyRef или GeAnTyRef (расширенный форк, который я поддерживать).

StringConsumer consumer = new StringConsumer(); //Or LongConsumer

Field a = consumer.getClass().getDeclaredField("a");
//typeOfA represents A<String, String>
ParameterizedType typeOfA = (ParameterizedType) GenericTypeReflector.getExactFieldType(a, consumer.getClass());

Type[] args =  typeOfA.getActualTypeArguments();
System.out.println(args[0]); //String
System.out.println(args[1]); //String

Field b = A.class.getDeclaredField("b");
//or if you need it dynamic ((Class)typeOfA.getRawType()).getDeclaredField("b")
//or GenericTypeReflector.erase(typeOfA).getDeclaredField("b")
//typeOfB represents B<String>
ParameterizedType typeOfB = (ParameterizedType) GenericTypeReflector.getExactFieldType(b, typeOfA);
System.out.println(typeOfB.getActualTypeArguments()[0]); //String again

Итак, что вы здесь делаете, начинаете с StringConsumer, получаете тип его поля a (typeOfA, то есть A<String, String>), затем используйте эту информацию для получения типа поля b ( typeOfB, что B<String>). Вы можете пойти так глубоко, как вам нужно ...

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