Get generic type of class at runtime

后端 未结 26 2493
野的像风
野的像风 2020-11-21 04:40

How can I achieve this?

public class GenericClass
{
    public Type getMyType()
    {
        //How do I return the type of T?
    }
}
相关标签:
26条回答
  • 2020-11-21 05:18

    It might be useful to someone. You can Use java.lang.ref.WeakReference; this way:

    class SomeClass<N>{
      WeakReference<N> variableToGetTypeFrom;
    
      N getType(){
        return variableToGetTypeFrom.get();
      }
    }
    
    0 讨论(0)
  • 2020-11-21 05:19

    Here is my trick:

    public class Main {
    
        public static void main(String[] args) throws Exception {
    
            System.out.println(Main.<String> getClazz());
    
        }
    
        static <T> Class getClazz(T... param) {
    
            return param.getClass().getComponentType();
        }
    
    }
    
    0 讨论(0)
  • 2020-11-21 05:21

    Here is working solution!!!

    @SuppressWarnings("unchecked")
        private Class<T> getGenericTypeClass() {
            try {
                String className = ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0].getTypeName();
                Class<?> clazz = Class.forName(className);
                return (Class<T>) clazz;
            } catch (Exception e) {
                throw new IllegalStateException("Class is not parametrized with generic type!!! Please use extends <> ");
            }
        } 
    

    NOTES: Can be used only as superclass
    1. Has to be extended with typed class (Child extends Generic<Integer>)
    OR

    2. Has to be created as anonymous implementation (new Generic<Integer>() {};)

    0 讨论(0)
  • 2020-11-21 05:21

    One simple solution for this cab be like below

    public class GenericDemo<T>{
        private T type;
    
        GenericDemo(T t)
        {
            this.type = t;
        }
    
        public String getType()
        {
            return this.type.getClass().getName();
        }
    
        public static void main(String[] args)
        {
            GenericDemo<Integer> obj = new  GenericDemo<Integer>(5);
            System.out.println("Type: "+ obj.getType());
        }
    }
    
    0 讨论(0)
  • 2020-11-21 05:22

    Generics are not reified at run-time. This means the information is not present at run-time.

    Adding generics to Java while mantaining backward compatibility was a tour-de-force (you can see the seminal paper about it: Making the future safe for the past: adding genericity to the Java programming language).

    There is a rich literature on the subject, and some people are dissatisfied with the current state, some says that actually it's a lure and there is no real need for it. You can read both links, I found them quite interesting.

    0 讨论(0)
  • 2020-11-21 05:22

    Use Guava.

    import com.google.common.reflect.TypeToken;
    import java.lang.reflect.Type;
    
    public abstract class GenericClass<T> {
      private final TypeToken<T> typeToken = new TypeToken<T>(getClass()) { };
      private final Type type = typeToken.getType(); // or getRawType() to return Class<? super T>
    
      public Type getType() {
        return type;
      }
    
      public static void main(String[] args) {
        GenericClass<String> example = new GenericClass<String>() { };
        System.out.println(example.getType()); // => class java.lang.String
      }
    }
    

    A while back, I posted some full-fledge examples including abstract classes and subclasses here.

    Note: this requires that you instantiate a subclass of GenericClass so it can bind the type parameter correctly. Otherwise it'll just return the type as T.

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