Comments 6
Нельзя получить Class для параметризованного типа
package tests;
import java.lang.reflect.ParameterizedType;
import java.util.List;
public class GenExample {
public List<String> strings;
static void main() {
var example = new GenExample();
example.test();
}
private void test() {
try {
var field = GenExample.class.getField("strings");
var type = (ParameterizedType) field.getGenericType();
System.out.println(type.getActualTypeArguments()[0]);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
}
}
}
// out: class java.lang.String
Нельзя получить class literal параметризованного типа

Может у меня какая-то Java неправильная?
И как тогда Spring в рантайме из интерфейсов репозитории создает?
Class literal — это не то же самое, что метаданные объявления. Это развёрнуто уточняется в шестом пункте.
6. Нельзя получить class literal параметризованного типа
Вот так тоже нельзя:
Class<?> clazz = List<String>.class;
Потому что отдельного runtime-класса List<String> просто не существует. Существует только List.class.
То есть компилятор не может дать вам class literal для того, чего в runtime-модели нет.
Допустимый вариант выглядит так:
Class<?> clazz = List.class;При этом важно не путать Class с reflection API для generic-сигнатур. Если класс, поле или метод были объявлены с параметризованным типом, эту информацию можно прочитать через Type и ParameterizedType:
Field field = GenExample.class.getField("strings");
ParameterizedType type = (ParameterizedType) field.getGenericType();
System.out.println(type.getActualTypeArguments()[0]); // class java.lang.StringНо здесь мы получаем не Class<List<String>>, а метаданные объявления, сохранённые в class-файле.
Семь вещей, которые нельзя делать из-за стирания типов в Java