0

One of the generic classes that I'm extending requires that I return a Class object of the correct generic type. I know how to do this for the normal case, but not when my class contains a generic list.

For example, I know how to implement the first method below, but not the second:

public Class<String> getStringKlass() {
    return String.class;
}

public Class<List<String>> getStringListKlass() {
    ???
}
La-comadreja
  • 5,161
  • 8
  • 31
  • 59
Stephen Ostermiller
  • 18,578
  • 8
  • 74
  • 95
  • See also http://stackoverflow.com/questions/339699/java-generics-type-erasure-when-and-what-happens – Smutje Mar 11 '14 at 19:46
  • possible duplicate of [Java: how do I get a class literal from a generic type?](http://stackoverflow.com/questions/2390662/java-how-do-i-get-a-class-literal-from-a-generic-type) – Paul Bellora Mar 11 '14 at 19:52

3 Answers3

2

It's simple as

List.class

The generic information is there for compile-time. For runtime, generics are ignored and it's only the type of the class that matters.

Kashif Nazar
  • 14,651
  • 4
  • 23
  • 38
  • 1
    That doesn't compile. It gives me a "Type mismatch" error. – Stephen Ostermiller Mar 11 '14 at 19:53
  • @StephenOstermiller I'm guessing your method should return `Class` instead of `Class>`, but I don't know what problems this might cause, and maybe it should be returning something like `Class>`. But I'm not an expert in this area. – ajb Mar 11 '14 at 20:03
  • Oops. I didn't mention. You will also need to refactor the signatures of your method to `public Class getKlass()` – Kashif Nazar Mar 11 '14 at 20:03
1

There's no way to do that due to type erasure: In Java, if you have a generic type (here: List<T>) then at compile-time you can use List<String>, List<Date>, etc. However, at runtime all these types are represented by the same Class object.

In other words, the following program will output true:

ArrayList<String> list = new ArrayList<String>();
System.out.println(list.getClass() == ArrayList.class);
Itay Maman
  • 28,289
  • 9
  • 76
  • 114
0

The closest I've gotten to achieve that is to create a new class that extends some List<String>.

public class ListOfStrings extends ArrayList<String> { }

And then using <? extends List<String>> instead of just List<String> in your method:

public Class<? extends List<String>> getStringListKlass()
{
    return ListOfStrings.class;
}

However, I don't know what sort of trouble this might introduce in your code after that.