简体   繁体   中英

Getting generic type of super interface via reflection

interface BaseDao<T> { }

interface UserDao extends BaseDao<User> { }

interface DeptDao extends BaseDao<Department> { }

I need a function get Entity class via Dao class, like this:

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

and I don't like add annotation to dao , like this:

@Entity(User.class)
interface UserDao extends BaseDao

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

inspired by dimo414 's suggestion, this is my solution:

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> {}

Take a look at Guava's TypeToken , which does what (I think) you're describing. More details in their Reflection Explained article.

The TypeCapture.capture() method gets the generic type of the parent class:

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

and that's how TypeToken 's "magic" works.

One way to make the class available in your code is to expose a method on your BaseDao

Class<T> getClassType();

then in your implementation you pass the class type in the constructor eg

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());
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM