tags:

views:

203

answers:

7

Hi all,

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

+4  A: 

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

Jon Skeet
Ew. Java is gross for this kind of thing.
Conrad Meyer
which honestly you shouldn't need if you design your classes properly.
Bozho
I understand, maybe my desing is bad.I have a view that can be applyed to 2 models, except for some little things depending on the type of the object model.I don't want to create 2 views that are quite the same, but they are not working exactly the same.
Tim
Tim: Some kind of inheritance or composition is the usual solution...
Tom Hawtin - tackline
(Or even a flag.)
Tom Hawtin - tackline
+5  A: 

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.

cletus
+1  A: 
if (object instanceof String)
   System.out.println("object is a string");
r3zn1k
I think that's actually a reasonable point given the question.
Tom Hawtin - tackline
A: 

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.

denis.zhdanov
A: 

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.

bertolami
A: 

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

fastcodejava
good point of view
Tim
A: 

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.

Thomas Jung