I have a generics class Foo<T>
. In a method of Foo
, i want to get the class instance of type T. But i just can't call T.class
Please tell me your preferred way to get around with the T.class
?
I have a generics class Foo<T>
. In a method of Foo
, i want to get the class instance of type T. But i just can't call T.class
Please tell me your preferred way to get around with the T.class
?
You can't do it because of type erasure.
See also: http://stackoverflow.com/questions/339699/java-generics-type-erasure-when-and-what-happens
It is not possible to get the class of a generic type parameter within the generic code. Type erasure prevents it.
The normal workaround is to explicitly pass the Class
object for the actual type as a parameter to the generic type's constructor. For example:
public class Foo<T> {
private Class<T> clazz;
public Foo(Class<T> clazz) {
this.clazz = clazz;
}
public void doSomething(...) {
T myT = clazz.newInstance();
...
}
}
The short answer is, that there is no way to find out the runtime type of generic type parameters in Java. I suggest reading the chapter about type erasure in the Java Tutorial for more details.
A popular solution to this is to pass the Class
of the type parameter into the constructor of the generic type, e.g.
class Foo<T> {
final Class<T> typeParameterClass;
public Foo(Class<T> typeParameterClass) {
this.typeParameterClass = typeParameterClass;
}
public void bar() {
// you can access the typeParameterClass here and do whatever you like
}
}
A standard approach/workaround/solution is to add a class
object to the constructor(s), like:
public class Foo<T> {
privat Class<T> type;
public Foo(Class<T> type) {
this.type = type;
}
public Class<T> getType() {
return type;
}
public T newInstance() {
return type.newInstance();
}
}
A better route than the Class the others suggested is to pass in an object that can do what you would have done with the Class, e.g., create a new instance.
interface Factory<T> {
T apply();
}
<T> void List<T> make10(Factory<T> factory) {
List<T> result = new ArrayList<T>();
for (int a = 0; a < 10; a++)
result.add(factory.apply());
return result;
}
class FooFactory implements Factory<Foo> {
public Foo apply() {
return new Foo();
}
}
List<Foo> foos = make10(new FooFactory());