I'm creating a generic class and in one of the methods I need to know the Class of the generic type currently in use. The reason is that one of the method's I call expects this as an argument.
Example:
public class MyGenericClass<T> { public void doSomething() { // Snip... // Call to a 3rd party lib T bean = (T)someObject.create(T.class); // Snip... } }
Clearly the example above doesn't work and results in the following error: Illegal class literal for the type parameter T.
My question is: does someone know a good alternative or workaround for this?
Pass the class object instead and it's easy. The idea here is that since you can't extract the type parameter from the object, you have to do it the other way around: start with the class and then manipulate the object to match the type parameter.
Use the IsGenericType property to determine whether the type is generic, and use the IsGenericTypeDefinition property to determine whether the type is a generic type definition. Get an array that contains the generic type arguments, using the GetGenericArguments method.
A Generic class simply means that the items or functions in that class can be generalized with the parameter(example T) to specify that we can add any type as a parameter in place of T like Integer, Character, String, Double or any other user-defined type.
A generic type is declared by specifying a type parameter in an angle brackets after a type name, e.g. TypeName<T> where T is a type parameter.
Still the same problems : Generic informations are erased at runtime, it cannot be recovered. A workaround is to pass the class T in parameter of a static method :
public class MyGenericClass<T> { private final Class<T> clazz; public static <U> MyGenericClass<U> createMyGeneric(Class<U> clazz) { return new MyGenericClass<U>(clazz); } protected MyGenericClass(Class<T> clazz) { this.clazz = clazz; } public void doSomething() { T instance = clazz.newInstance(); } }
It's ugly, but it works.
I was just pointed to this solution:
import java.lang.reflect.ParameterizedType; public abstract class A<B> { public Class<B> g() throws Exception { ParameterizedType superclass = (ParameterizedType) getClass().getGenericSuperclass(); return (Class<B>) superclass.getActualTypeArguments()[0]; } }
This works if A
is given a concrete type by a subclass:
new A<String>() {}.g() // this will work class B extends A<String> {} new B().g() // this will work class C<T> extends A<T> {} new C<String>().g() // this will NOT work
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With