How do I get a class instance of generic type T?

前端 未结 22 1247
猫巷女王i
猫巷女王i 2020-11-21 11:03

I have a generics class, Foo. In a method of Foo, I want to get the class instance of type T, but I just can\'t call T.

相关标签:
22条回答
  • 2020-11-21 11:54

    Many poeple don't know this trick! Actually, I just found it today! It works like a dream! Just check this example out:

    public static void main(String[] args) throws NoSuchMethodException {
        Date d=new Date();  //Or anything you want!
        printMethods(i);
    }
    
    public static <T> void printMethods(T t){
        Class<T> clazz= (Class<T>) t.getClass(); // There you go!
        for ( Method m : clazz.getMethods()){
            System.out.println( m.getName() );
        }
    }
    
    0 讨论(0)
  • 2020-11-21 11:56
       public <T> T yourMethodSignature(Class<T> type) {
    
            // get some object and check the type match the given type
            Object result = ...            
    
            if (type.isAssignableFrom(result.getClass())) {
                return (T)result;
            } else {
                // handle the error
            }
       }
    
    0 讨论(0)
  • 2020-11-21 12:00

    You can't do it because of type erasure. See also Stack Overflow question Java generics - type erasure - when and what happens.

    0 讨论(0)
  • 2020-11-21 12:01

    If you are extending or implementing any class/interface that are using generics , you may get the Generic Type of parent class/interface, without modifying any existing class/interface at all.

    There could be three possibilities,

    Case 1 When your class is extending a class that is using Generics

    public class TestGenerics {
        public static void main(String[] args) {
            Type type = TestMySuperGenericType.class.getGenericSuperclass();
            Type[] gTypes = ((ParameterizedType)type).getActualTypeArguments();
            for(Type gType : gTypes){
                System.out.println("Generic type:"+gType.toString());
            }
        }
    }
    
    class GenericClass<T> {
        public void print(T obj){};
    }
    
    class TestMySuperGenericType extends GenericClass<Integer> {
    }
    

    Case 2 When your class is implementing an interface that is using Generics

    public class TestGenerics {
        public static void main(String[] args) {
            Type[] interfaces = TestMySuperGenericType.class.getGenericInterfaces();
            for(Type type : interfaces){
                Type[] gTypes = ((ParameterizedType)type).getActualTypeArguments();
                for(Type gType : gTypes){
                    System.out.println("Generic type:"+gType.toString());
                }
            }
        }
    }
    
    interface GenericClass<T> {
        public void print(T obj);
    }
    
    class TestMySuperGenericType implements GenericClass<Integer> {
        public void print(Integer obj){}
    }
    

    Case 3 When your interface is extending an interface that is using Generics

    public class TestGenerics {
        public static void main(String[] args) {
            Type[] interfaces = TestMySuperGenericType.class.getGenericInterfaces();
            for(Type type : interfaces){
                Type[] gTypes = ((ParameterizedType)type).getActualTypeArguments();
                for(Type gType : gTypes){
                    System.out.println("Generic type:"+gType.toString());
                }
            }
        }
    }
    
    interface GenericClass<T> {
        public void print(T obj);
    }
    
    interface TestMySuperGenericType extends GenericClass<Integer> {
    }
    
    0 讨论(0)
  • 2020-11-21 12:02

    I have an (ugly but effective) solution for this problem, which I used recently:

    import java.lang.reflect.TypeVariable;
    
    
    public static <T> Class<T> getGenericClass()
    {
        __<T> ins = new __<T>();
        TypeVariable<?>[] cls = ins.getClass().getTypeParameters(); 
    
        return (Class<T>)cls[0].getClass();
    }
    
    private final class __<T> // generic helper class which does only provide type information
    {
        private __()
        {
        }
    }
    
    0 讨论(0)
  • 2020-11-21 12:03

    It's possible:

    class Foo<T> {
      Class<T> clazz = (Class<T>) DAOUtil.getTypeArguments(Foo.class, this.getClass()).get(0);
    }
    

    You need two functions from hibernate-generic-dao/blob/master/dao/src/main/java/com/googlecode/genericdao/dao/DAOUtil.java.

    For more explanations, see Reflecting generics.

    0 讨论(0)
提交回复
热议问题