I have a generic class, says :
MyClass
Inside a method of this class, I would like to test the type of T, for example :
Additionally to cletus one exception I've mine: super type tokens. The super type token will preserve the type information.
new Type<Set<Integer>>() {}
The type information can be retrieved with Class.getGenericSuperClass.
As it was already stated you can get only generics-related information available at the static byte code level.
It's possible to resolve type arguments values and check if one type may be used in place of another then.
Because of type erasure you can't... mostly. But there is one exception to that. Consider:
class A {
List<String> list;
}
public class Main {
public static void main(String args[]) {
for (Field field : A.class.getDeclaredFields()) {
System.out.printf("%s: %s%n", field.getName(), field.getGenericType());
}
}
}
Output:
list: java.util.List<java.lang.String>
If you need the class object, this is how you generally handle it:
public <T> T createObject(Class<T> clazz) {
return clazz.newInstance();
}
ie by passing the class object around and deriving the generic type from that class.
if (object instanceof String)
System.out.println("object is a string");
You can't, normally, due to type erasure. See Angelika Langer's Java Generics FAQ for more details.
What you can do is pass a Class<T>
into your constructor, and then check that:
public MyClass<T>
{
private final Class<T> clazz;
public MyClass(Class<T> clazz)
{
this.clazz = clazz;
}
public void myMethod()
{
if (clazz == String.class)
{
...
}
}
}
Note that Java does not allow primitives to be used for type arguments though, so int
is out...
if you have subclass B extends A
that should match, too, the approach clazz == A.class
. Doesn't work. You should then use A.class.isInstance(b)
where b is an object of type B.