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.
You can get the name of the generics from the subclass. See this example. We Define a parent class like this:
We then define its child class in this way:
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.
Short answer: Impossible.
Slightly longer answer: Once your code is compiled, the type parameters is discarded. Thus, Java cannot know what you set there. You could, however, pass the class in question to your object and operate on it:
As is normally the case, Apache has a solution for this one with TypeUtils:
https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/reflect/TypeUtils.html
A quick example from the above question:
Disclaimer: I did not attempt building this first, but have used this utility in a similar fashion in the past.
Generics in Java are implemented by erasure, so no, you won't be able to get the name of the "type" which was used to create your generic collection at run-time. Also, why not just inspect the elements to know what type it belongs to?
You can't do this in general because of type erasure - an instance of
A<String>
doesn't know the type ofT
. If you need it, one way is to use a type literal:Then:
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
now refers to a subclass ofA<String>
, so by gettinga.getClass().getSuperClass()
you can eventually get back toString
. It's pretty horrible though.This certainly is possible so long as the type argument is specified via a subclass of A:
TypeResolver is available via TypeTools.