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

新手上路,请多包涵

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

使用 T.class 绕过它的首选方法是什么?

原文由 robinmag 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 655
2 个回答

简短的回答是,没有办法找出 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
    }
}

原文由 Zsolt Török 发布,翻译遵循 CC BY-SA 2.5 许可协议

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

Most generics use cases I’ve come across have some kind of generic supertype eg List<T> for ArrayList<T> or GenericDAO<T> for DAO<T> , etc.

纯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

原文由 Ben Thurley 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题