I have a small problem in java while using genericity. I have a class A
:
public class A<T>
In a method of A
, I need to get the type name of T
.
Is there a way to find the string s
using T
?
(If I create A<String> temp = new A<String>();
, I want to be able to get java.lang.String
at one point - I have to use genericity because one of my methods will have to return a List<T>
).
This seems quite easy but I do not see how to do it.
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 can have muliple type parameters.
In order to use a generic type we must provide one type argument per type parameter that was declared for the generic type. The type argument list is a comma separated list that is delimited by angle brackets and follows the type name. The result is a so-called parameterized type.
Not really. You need to use reflection, basically. Generics are really aimed at static typing rather than types only known at execution time.
You can't do this in general because of type erasure - an instance of A<String>
doesn't know the type of T
. If you need it, one way is to use a type literal:
public class A<T>
{
private final Class<T> clazz;
public A<T>(Class<T> clazz)
{
this.clazz = clazz;
}
// Use clazz in here
}
Then:
A<String> x = new A<String>(String.class);
It's ugly, but that's what type erasure does :(
An alternative is to use something like Guice's TypeLiteral
. This works because the type argument used to specify a superclass isn't erased. So you can do:
A<String> a = new A<String>() {};
a
now refers to a subclass of A<String>
, so by getting a.getClass().getSuperClass()
you can eventually get back to String
. It's pretty horrible though.
You can get the name of the generics from the subclass. See this example. We Define a parent class like this:
public class GetTypeParent<T> {
protected String getGenericName()
{
return ((Class<T>) ((ParameterizedType) getClass()
.getGenericSuperclass()).getActualTypeArguments()[0]).getTypeName();
}
}
We then define its child class in this way:
public class GetTypeChild extends GetTypeParent<Integer> {
public static void main(String[] args) {
GetTypeChild getTypeChild = new GetTypeChild();
System.out.println(getTypeChild.getGenericName());
}
}
You can see that in the main method, or in any instance method, I am capable to get the name of the generics type, in this case the main will print: java.lang.Integer.
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