2

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().

Jérôme Verstrynge
  • 57,710
  • 92
  • 283
  • 453
  • 1
    not sure what you mean. if you have the Class instance already, what more do you want? – jtahlborn Jul 30 '12 at 18:19
  • The type used as the generic parameter. – Jérôme Verstrynge Jul 30 '12 at 18:28
  • 1
    of _what_? a Class instance or some type name? maybe you could add some pseudo code indicating what you are looking for... – jtahlborn Jul 30 '12 at 18:41
  • in your question you are using "Class". do you mean the Java class `Class`, or do you mean, "some unspecified class type"? – jtahlborn Jul 30 '12 at 18:42
  • Of the class. In my example, that would be String as indicated in the question. – Jérôme Verstrynge Jul 30 '12 at 18:42
  • In what form do you want it? What do you expect to be returned? A `String` holding the class name? If you want "the type" to be returned, the only way for that desire to make sense is...to get a `Class`, which you already have. – Louis Wasserman Jul 30 '12 at 20:42
  • A Type tt where System.out.println(tt) would print something like this: java.lang.String. – Jérôme Verstrynge Jul 30 '12 at 20:48
  • The only thing similar to `Method.getGenericReturnType` for a class is `Class.getGenericSuperclass()` and `Class.getGenericSuperinterfaces()`, which means you can only retrieve type information for an object that is passed into a superclass as part of that object's class declaration. Fully resolving this type information can be a pain since it can consist of TypeParameters that are scattered around your type hierarchy. See my response below for more info... – Jonathan Jul 30 '12 at 21:21

4 Answers4

2

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.

Community
  • 1
  • 1
kosa
  • 65,990
  • 13
  • 130
  • 167
1

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.

Hari Gudigundla
  • 812
  • 10
  • 20
1

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.

erickson
  • 265,237
  • 58
  • 395
  • 493
0

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 
Jérôme Verstrynge
  • 57,710
  • 92
  • 283
  • 453