Вебинары Разобраться в IT Реферальная программа
Программирование Аналитика Дизайн Маркетинг Управление проектами
7 профессий по цене одной
07:05:47:06
дн. ч. мин. сек.
22 Июл 2024
2 мин
94

Получение обобщенного типа класса во время выполнения

При работе с обобщенными классами в Java часто возникает ситуация, когда требуется получить тип этого обобщенного класса во время выполнения. Например,

При работе с обобщенными классами в Java часто возникает ситуация, когда требуется получить тип этого обобщенного класса во время выполнения. Например, имеется следующий обобщенный класс:

public class GenericClass<T> {
    private T t;

    public void setValue(T t) {
        this.t = t;
    }

    public T getValue() {
        return t;
    }
}

Используя этот класс, можно создать объекты разных типов, таких как GenericClass<String> или GenericClass<Integer>. Но вопрос в том, как получить этот тип во время выполнения?

Попытки получить тип с помощью метода getClass() не принесут успеха, так как все обобщенные типы в Java стираются во время компиляции (известно как «стирание типов») и заменяются на свои верхние границы, в нашем случае — на класс Object.

GenericClass&lt;String&gt; stringGenericClass = new GenericClass&lt;&gt;();
System.out.println(stringGenericClass.getClass().getTypeParameters()[0]); // Вывод: T

Как видно из примера, такой подход возвращает только имя параметра типа, а не фактический тип.

Один из способов получить обобщенный тип класса во время выполнения — это использование рефлексии в сочетании с анонимными внутренними классами. Например:

public abstract class GenericClass&lt;T&gt; {
    protected final Class&lt;T&gt; type;

    @SuppressWarnings("unchecked")
    public GenericClass() {
        this.type = (Class&lt;T&gt;) ((ParameterizedType) getClass()
                .getGenericSuperclass()).getActualTypeArguments()[0];
    }

    public Class&lt;T&gt; getMyType() {
        return this.type;
    }
}

GenericClass&lt;String&gt; stringGenericClass = new GenericClass&lt;String&gt;() {};
System.out.println(stringGenericClass.getMyType()); // Вывод: class java.lang.String

В этом примере GenericClass теперь является абстрактным классом, и в конструкторе используется рефлексия для извлечения фактического типа параметра. Таким образом, при создании анонимного подкласса GenericClass<String>, фактический тип параметра сохраняется и может быть извлечен во время выполнения.

Тем не менее, стоит учесть, что это решение имеет свои ограничения и может не работать в некоторых случаях. Прежде всего, это связано с тем, что рефлексия — это достаточно мощный инструмент, который следует использовать с осторожностью, так как он может привести к неожиданным последствиям.

Проверь как ты усвоил материалы статьи
Пройди тест и узнай насколько ты лучше других читателей

Добавить комментарий