Pull to refresh

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 для List получить нельзя, а информацию о том, что поле было объявлено как List, получить можно. Надо переписать этот пункт, чтобы было точнее, сейчас подумаю, как.

Да! Писал как-то такой код в тестах :-)

Вероятно, стоило отдельно написать про метаданные. Готово

Нельзя получить class literal параметризованного типа

Здесь класс Field не из пакета рефлексии, если что
Здесь класс Field не из пакета рефлексии, если что

Может у меня какая-то 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-файле.

Sign up to leave a comment.

Articles