如何获取泛型类型 T 的类实例?

2022-08-31 04:04:26

我有一个泛型类,.在的方法中,我想得到类型的类实例,但我就是不能调用。Foo<T>FooTT.class

使用哪种更好的方法来绕过它?T.class


答案 1

简短的回答是,在Java中没有办法找出泛型类型参数的运行时类型。我建议阅读 Java 教程中有关类型擦除的章节,了解更多详情。

一种流行的解决方案是将类型参数传递到泛型类型的构造函数中,例如Class

class Foo<T> {
    final Class<T> typeParameterClass;

    public Foo(Class<T> typeParameterClass) {
        this.typeParameterClass = typeParameterClass;
    }

    public void bar() {
        // you can access the typeParameterClass here and do whatever you like
    }
}

答案 2

我正在寻找一种方法来自己执行此操作,而无需向类路径添加额外的依赖项。经过一些调查,我发现只要你有一个通用的超类型,这是可能的。这对我来说没关系,因为我正在使用具有通用层超类型的DAO层。如果这符合您的情况,那么恕我直言,这是最整洁的方法。

我遇到的大多数泛型用例都有某种泛型超类型,例如 for 或 for 等。List<T>ArrayList<T>GenericDAO<T>DAO<T>

纯 Java 解决方案

Java 中运行时访问泛型类型一文介绍了如何使用纯 Java 执行此操作。

@SuppressWarnings("unchecked")
public GenericJpaDao() {
  this.entityBeanType = ((Class) ((ParameterizedType) getClass()
      .getGenericSuperclass()).getActualTypeArguments()[0]);
}

弹簧解决方案

我的项目是使用Spring,这甚至更好,因为Spring有一个方便的实用程序方法来查找类型。这对我来说是最好的方法,因为它看起来最整洁。我想如果你没有使用Spring,你可以编写自己的实用程序方法。

import org.springframework.core.GenericTypeResolver;

public abstract class AbstractHibernateDao<T extends DomainObject> implements DataAccessObject<T>
{

    @Autowired
    private SessionFactory sessionFactory;

    private final Class<T> genericType;

    private final String RECORD_COUNT_HQL;
    private final String FIND_ALL_HQL;

    @SuppressWarnings("unchecked")
    public AbstractHibernateDao()
    {
        this.genericType = (Class<T>) GenericTypeResolver.resolveTypeArgument(getClass(), AbstractHibernateDao.class);
        this.RECORD_COUNT_HQL = "select count(*) from " + this.genericType.getName();
        this.FIND_ALL_HQL = "from " + this.genericType.getName() + " t ";
    }

完整代码示例

有些人在评论中挣扎着让它工作,所以我写了一个小应用程序来展示这两种方法的实际效果。https://github.com/benthurley82/generic-type-resolver-test


推荐