Tim
Tim

Reputation: 2917

Knowing type of generic in Java

I have a generic class, says :

MyClass<T>

Inside a method of this class, I would like to test the type of T, for example :

void MyMethod()
{

    if (T == String)
        ...
    if (T == int)
        ...
}

how can I do that ?

Thanks for your help

Upvotes: 5

Views: 12677

Answers (7)

Thomas Jung
Thomas Jung

Reputation: 33092

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.

Upvotes: 3

fastcodejava
fastcodejava

Reputation: 41097

If you want to do different things for different types would it still be generic?

Upvotes: 0

bertolami
bertolami

Reputation: 2936

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.

Upvotes: 0

denis.zhdanov
denis.zhdanov

Reputation: 3744

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.

Upvotes: 0

oliver31
oliver31

Reputation: 2523

if (object instanceof String)
   System.out.println("object is a string");

Upvotes: 1

cletus
cletus

Reputation: 625077

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.

Upvotes: 8

Jon Skeet
Jon Skeet

Reputation: 1500525

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...

Upvotes: 12

Related Questions