Получить имя типа для универсального параметра универсального класса [duplicate]

Я хотел отфильтровать строки dfbc, у которых был BUSINESS_ID, который также был в BUSINESS_ID dfProfilesBusIds

. Наконец, он работал:

dfbc = dfbc[(dfbc['BUSINESS_ID'].isin(dfProfilesBusIds['BUSINESS_ID']) == False)]
29
задан ROMANIA_engineer 23 September 2018 в 17:51
поделиться

6 ответов

Вы не можете сделать это вообще из-за стирания типа - экземпляр A<String> не знает тип T. Если вам это нужно, одним из способов является использование литерала типа:

public class A<T>
{
    private final Class<T> clazz;

    public A<T>(Class<T> clazz)
    {
        this.clazz = clazz;
    }

    // Use clazz in here
}

Тогда:

A<String> x = new A<String>(String.class);

Это ужасно, но вот что делает стирание типа: (

Альтернативой является использование чего-то вроде TypeLiteral Гисе. Это работает, потому что аргумент типа, используемый для указания суперкласса , не удаляется. Поэтому вы можете сделать: 112]

a теперь относится к подклассу из A<String>, поэтому, получив a.getClass().getSuperClass(), вы можете в конечном итоге вернуться к String. Это довольно ужасно.

42
ответ дан Jon Skeet 23 September 2018 в 17:51
поделиться

Это, безусловно, возможно, если аргумент типа указан через подкласс A:

public class B extends A<String> {}

Class<?> typeArg = TypeResolver.resolveRawArgument(A.class, B.class);
assert typeArg == String.class;

TypeResolver доступен через TypeTools .

5
ответ дан Jonathan 23 September 2018 в 17:51
поделиться

Вы можете получить название дженериков из подкласса. Смотрите этот пример. Определим родительский класс следующим образом:

public class GetTypeParent<T> {

    protected String getGenericName()
    {
        return ((Class<T>) ((ParameterizedType) getClass()
                .getGenericSuperclass()).getActualTypeArguments()[0]).getTypeName();
    }
}

Затем мы определим его дочерний класс следующим образом:

public class GetTypeChild extends GetTypeParent<Integer> {
    public static void main(String[] args) {
        GetTypeChild getTypeChild = new GetTypeChild();
        System.out.println(getTypeChild.getGenericName());
    }
}

Это можно увидеть в методе main или в любом методе экземпляра. , Я могу получить имя типа generics, в этом случае основной выводит: java.lang.Integer .

24
ответ дан Enrico Giurin 23 September 2018 в 17:51
поделиться

Если вы делаете это в подклассе, у которого есть родительский класс, определяющий универсальный тип, это то, что сработало для меня:

// get generic type class name
String name = ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0].toString();

// then when you've got the name, you can make the Class<T> object
Class.forName(name.replace("class ", ""))

Причина, почему я не мог сделать это с #getClass() вместо #toString() в первом отрывке говорится, что я всегда получал класс «Класс», который для меня бесполезен.

1
ответ дан milosmns 23 September 2018 в 17:51
поделиться

Краткий ответ: невозможно.

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

public class A<T> {
  private final clazz;

  A(Class<T> clazz){
     this.clazz = clazz;
  }
...
}
9
ответ дан Urs Reupke 23 September 2018 в 17:51
поделиться

Как обычно, у Apache есть решение для этого с TypeUtils:

https://commons.apache.org/proper/commons-lang/apidocs/org/apache/ commons / lang3 / рефлексия / TypeUtils.html

Быстрый пример из приведенного выше вопроса:

TypeUtils.getTypeArguments(temp.getClass(), A.class).get(A.class.getTypeParameters()[0])

Отказ от ответственности: я не пытался сначала построить это, но использовал эту утилиту аналогичным образом в прошлом.

1
ответ дан Hazok 23 September 2018 в 17:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: