Sobes.tech
Middle+

Възможно ли е по време на изпълнение на програмата да се получи достъп до типа на генерика?

sobes.tech AI

Отговор от 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 се губи по време на изпълнение

В контекста на 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> и може да се използва по време на изпълнение