获取抽象超类的泛型类型参数的实际类型 [英] Get actual type of generic type argument on abstract superclass

查看:590
本文介绍了获取抽象超类的泛型类型参数的实际类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类如下:

  public abstract class BaseDao< T extends PersistentObject> {

protected Class< T> getClazz(){
return T.class;
}

// ...

}

但是编译器对 T.class; 类型参数T 。



如何获得 T

解决方案

绝对可以从 Class#getGenericSuperclass() ,因为它没有在运行时定义,但是在编译期间被 FooDao extends BaseDao< ;富>

以下是一个启发式示例,您可以在抽象类的构造函数中抽取所需的泛型超类型,并考虑子类的层次结构(以及真实世界的使用在不需要显式提供类型的情况下将其应用于通用 EntityManager 方法): code> public abstract class BaseDao< E extends BaseEntity> {

@PersistenceContext
私人EntityManager em;

私人班级< E>类型;

@SuppressWarnings(unchecked)//用于Class< E>的类型转换。
public BaseDao(){
Type type = getClass()。getGenericSuperclass(); $($)
$ b while(!(typeof instanceof ParameterizedType)||((ParameterizedType)type).getRawType()!= BaseDao.class){
if(type instanceof ParameterizedType){
type =((Class<>)((ParameterizedType)type).getRawType())。getGenericSuperclass();
} else {
type =((Class<>)类型).getGenericSuperclass(); $(b)


$ b this.type =(Class< E>)((ParameterizedType)type).getActualTypeArguments()[0];
}

public E find(Long id){
return em.find(type,id);
}

public List< E> list(){
return em.createQuery(String.format(SELECT e FROM%s e ORDER BY id,type.getSimpleName()),type).getResultList();
}

// ...
}


I have a class like:

public abstract class BaseDao<T extends PersistentObject> {

  protected Class<T> getClazz() {
     return T.class;
  }

  // ...

}

But the compiler says to T.class;: Illegal class literal for the type parameter T.

How can I get the class of T?

解决方案

It's definitely possible to extract it from Class#getGenericSuperclass() because it's not defined during runtime, but during compiletime by FooDao extends BaseDao<Foo>.

Here's a kickoff example how you could extract the desired generic super type in the constructor of the abstract class, taking a hierarchy of subclasses into account (along with a real world use case of applying it on generic EntityManager methods without the need to explicitly supply the type):

public abstract class BaseDao<E extends BaseEntity> {

    @PersistenceContext
    private EntityManager em;

    private Class<E> type;

    @SuppressWarnings("unchecked") // For the cast on Class<E>.
    public BaseDao() {
        Type type = getClass().getGenericSuperclass();

        while (!(type instanceof ParameterizedType) || ((ParameterizedType) type).getRawType() != BaseDao.class) {
            if (type instanceof ParameterizedType) {
                type = ((Class<?>) ((ParameterizedType) type).getRawType()).getGenericSuperclass();
            } else {
                type = ((Class<?>) type).getGenericSuperclass();
            }
        }

        this.type = (Class<E>) ((ParameterizedType) type).getActualTypeArguments()[0];
    }

    public E find(Long id) {
        return em.find(type, id);
    }

    public List<E> list() {
        return em.createQuery(String.format("SELECT e FROM %s e ORDER BY id", type.getSimpleName()), type).getResultList();
    }

    // ...
}

这篇关于获取抽象超类的泛型类型参数的实际类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆