Posted tagged ‘type parameter’

Getting the Type of a generic class at runtime

10. Oktober 2008

How should I get the type of a parametrized class? … mmh … let me explain what mean:

import java.util.ArrayList;

public class Generic<T> {
  @Override
  public String toString() {
    return "Type Parameter is unknown.";
  }

  public static void main(String[] args) {
    System.out.println(new Generic<String>());
    System.out.println(new Generic<Integer>());
    System.out.println(new Generic<ArrayList>());
  }
}

and the output is (as expected)

Type Parameter is unknown.
Type Parameter is unknown.
Type Parameter is unknown.

But I want to have

Type Parameter is java.lang.String.
Type Parameter is java.lang.Integer.
Type Parameter is java.util.ArrayList.

The problem is that the „type erasure“ erased exactly that information. But the compiler does something with that information. Otherwise – why having that? Ok, I dont know any reflection API or getter for that. (As I said: type erasure). But maybe I can write a workaround …

Ok, what about having a member variable of type T and asking for its type?

public class Generic<T> {
  T type;

  public Class getGenericType() {
    return type.getClass();
  }

  @Override
  public String toString() {
    return "Type Parameter  is " + getGenericType().getName() + ".";
  }
}

The main-method is unchanged. But in that case I get a NullPointerException because the field is not initialized. But how to do that? Ok, no idea … but maybe I can now ask the reflection API …

Getting the field is easy

Field field = this.getClass().getField("type");</code>

but with the field I cant do any meaningful 😦

System.out.println(field.getGenericType()); // T
System.out.println(field.getType()); // class java.lang.Object
System.out.println(field.getDeclaringClass()); // class MyGeneric

Sadly type erasure hit me again, so field.getType() returns the class which can catch all possibilities: java.lang.Object. If I change the type parameter from Generic to Generic (just for the String-invocation in main()) I’ll get java.lang.CharSequence. In that case the global superclass Object isnt required any more.

But the result: I dont know how to get the type parameter … Maybe I should investigate in initializing the field and asking the real object for its type.