1

I have a generic method, how could I get the class of T?

class MyClass
{
    static <T> void foo(T t)
    {
        // how to get T.class
    }
}

t.getClass() gets the most derived class, but T could be a super class so it does not work in case of MyClass.<Collection>foo(new ArrayList()).

Isaac Hsu
  • 189
  • 1
  • 10
  • 4
    It's impossible. Read about type erasure. The best you can do is add another parameter `Class clazz` to the method. – Paul Boddington Apr 03 '16 at 19:37
  • `T` is `Object` at compile time in this case, so `Object.class` does the trick. Otherwise, how about `t.getClass()`? P.S. don't let anyone tell you this has anything to do with erasure, it doesn't; you haven't defined any bounds for `T`. – Boris the Spider Apr 03 '16 at 19:39
  • ```T``` is the _weak_ type, however ```getClass()``` returns the class of the _strong_ type. See [this question](http://stackoverflow.com/questions/106336/how-do-i-find-out-what-type-each-object-is-in-a-arraylistobject) – Jorn Vernee Apr 03 '16 at 19:41
  • @PaulBoddington erasure has nothing to do this this at all. `T` is `Object` because there are no bounds, so at compile time `T` becomes `Object`. At run time, then `t.getClass` gets the type of the variable passed in. – Boris the Spider Apr 03 '16 at 19:42
  • 1
    @BoristheSpider But if the OP does `MyClass.foo("bar")`, he wants to be able to get `CharSequence.class` at runtime inside the method. This is impossible due to type erasure. – Paul Boddington Apr 03 '16 at 19:44
  • @PaulBoddington type erasure is an implementation detail. Generics in Java are present at runtime and [easily accessed](http://stackoverflow.com/a/1901275/2071828). This issue is that `T` _does nothing_ here. – Boris the Spider Apr 03 '16 at 19:49

1 Answers1

2

If you want to keep your signature it is not possible. However, there's a way to solve this by providing the type as a separate argument.

static <T> void foo(T t, Class<T> cls) {
   // use cls
}

Then instead of invoking

MyClass.<Collection> foo(new ArrayList());

you call

MyClass.foo(new ArrayList(), Collection.class);
nyname00
  • 2,496
  • 2
  • 22
  • 25