通过反射获得泛型类型的超级接口

时间:2017-02-04 08:17:25

标签: java reflection

interface BaseDao<T> { }

interface UserDao extends BaseDao<User> { }

interface DeptDao extends BaseDao<Department> { }

我需要通过Entity类获取函数get Dao类,如下所示:

func(UserDao.class) return User.class
func(DeptDao.class) return Deparment.class  

喜欢将annotation添加到dao,如下所示:

@Entity(User.class)
interface UserDao extends BaseDao

----------------------------------------------- ----------

受dimo414建议的启发,这是我的解决方案:

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public class Main {

public static void main(String[] args) {
    // if A and B are Class, then it be 'B.class.getGenericSuperclass()'
    Type genType = B.class.getGenericInterfaces()[0];

    if (genType instanceof ParameterizedType) {
        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
        Class<?> clz = (Class) params[0];
        System.out.println(clz); // class java.lang.String
    }
}}

interface A<T> {}

interface B extends A<String> {}

2 个答案:

答案 0 :(得分:1)

看一下Guava的TypeToken,它会完成您所描述的(我认为)。有关Reflection Explained文章的详细信息。

TypeCapture.capture()方法获取父类的泛型类型:

Type capture() {
  Type superclass = getClass().getGenericSuperclass();
  checkArgument(superclass instanceof ParameterizedType, "%s isn't parameterized", superclass);
  return ((ParameterizedType) superclass).getActualTypeArguments()[0];
}

这就是TypeToken“神奇”的作用。

答案 1 :(得分:0)

在您的代码中使类可用的一种方法是在BaseDao上公开一个方法

Class<T> getClassType();

然后在您的实现中,您将在构造函数中传递类类型,例如

public class AbstractDao<T> implements BaseDao<T> {

    private Class<T> clasType;

    public AbstractDao(Class<T> clasType) {
        this.clasType = clasType;
    }

    public Class<T> getClassType() {
        return clasType;
    }
}


public class UserDaoImpl extends AbstractDao<User> implements UserDao     {

    public UserDaoImpl() {
        super(User.class);
    }

    public static void main(String[] args) {
        UserDaoImpl dao = new UserDaoImpl();
        System.out.print(dao.getClassType());
    }
}