Назад к вопросам
Middle+
73
questionbank

Можно ли в процессе выполнения программы получить доступ к типу дженерика?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

Нет, нельзя. Информация о типе дженерика стирается во время компиляции (type erasure). Во время выполнения доступны только "сырые" типы.

Например:

List<String> strings = new ArrayList<>();
// Во время выполнения программы эта информация будет утеряна:
// type erasure

Поэтому следующий код не сработает так, как можно ожидать:

if (list instanceof List<String>) { // Ошибка компиляции или предупреждение
    // Этот код не будет работать как проверка на List<String>
}

Можно получить доступ к информации о типе дженерика через рефлексию, но только в определенных случаях, например, при работе с полями, методами или сигнатурами классов, где тип был явно указан в исходном коде.

Пример получения типа коллекции из поля:

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

public class MyClass {
    List<String> stringList;

    public static void main(String[] args) throws Exception {
        Field field = MyClass.class.getDeclaredField("stringList");
        Type genericType = field.getGenericType(); // Получаем Type, содержащий информацию о <>

        if (genericType instanceof ParameterizedType) { // Проверяем, является ли тип параметризованным
            ParameterizedType parameterizedType = (ParameterizedType) genericType;
            Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); // Получаем аргументы типа

            for (Type type : actualTypeArguments) {
                System.out.println("Тип элемента: " + type.getTypeName()); // Выведет "java.lang.String"
            }
        }
    }
}

Но получить тип элемента листа, созданного динамически, уже не выйдет:

List<Integer> intList = new ArrayList<>();
// Здесь информация о Integer утеряна в runtime

В контексте Android это особенно важно учитывать при работе с библиотеками, использующими дженерики, например, Retrofit для парсинга ответов с API. Там часто используются конструкции типа TypeToken из Guava или его аналоги для передачи информации о типе во время выполнения.

Пример использования TypeToken (из Guava):

import com.google.common.reflect.TypeToken;
import java.util.List;

Type listStringType = new TypeToken<List<String>>() {}.getType();
// Этот объект Type содержит информацию о List<String> и может использоваться в runtime