简体   繁体   中英

Is it possible to retrieve the generic type used for a type token (i.e. Class<T>) at runtime?

Neal Gafter introduced type tokens (for example Class<String> ). Assuming one has access to an instance of Class<String> at runtime, is it possible to retrieve the generic type ( String ) at runtime?

I am looking for something similar to Method.getGenericReturnType() .

I think it is only possible for Fields/Methods. We can't get class specific generic type at runtime due to type erasure. It seems there is hack you can do if you have access to class. Read this discussion .

Unlike C#, Generics don't exist at run-time in Java. So you cannot try to create an instance of generic type or try to find type of a generic type at run-time.

It sounds like what you want is ParameterizedType .

You get these by reflecting on a Class and objects that come from it ( Method , Field ). However, you can't get a ParameterizedType from any old Class object; you can obtain one from a Class instance that represents a type that extends a generic class or interface.

It is possible using a variation of Bob Lee's elaboration of Gafter's Gadget pattern:

public class GenericTypeReference<T> {

    private final Type type;

    protected GenericTypeReference() {
        Type superclass = getClass().getGenericSuperclass();
        if (superclass instanceof Class) {
            throw new RuntimeException("Missing type parameter.");
        }
        this.type = ((ParameterizedType) superclass).getActualTypeArguments()[0];
    }

    public Type getType() {
        return this.type;
    }   

    public static void main(String[] args) {

        // This is necessary to create a Class<String> instance
        GenericTypeReference<Class<String>> tr =
            new GenericTypeReference<Class<String>>() {};

        // Retrieving the Class<String> instance
        Type c = tr.getType();

        System.out.println(c);
        System.out.println(getGenericType(c));

    }

    public static Type getGenericType(Type c) {
        return ((ParameterizedType) c).getActualTypeArguments()[0];
    }

}

The above code prints:

java.lang.Class<java.lang.String>
class java.lang.String 

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