7

Hi is there any way in Java to get staticly generic class type

I have ended up with construct

    List<TaskLocalConstraints> l = new ArrayList<TaskLocalConstraints>();
    Class<List<TaskLocalConstraints>> c = (Class<List<TaskLocalConstraints>>)l.getClass();

I am wondering, if there exists something like:

    Class c = List<TaskLocalConstraints>.class;

(I really dont want to construct new Object just to get its type)

Thanks

malejpavouk
  • 4,297
  • 6
  • 41
  • 67

5 Answers5

7

Since all List<something> classes actually correspond to the same class at runtime, you could do this:

Class<List<TaskLocalConstraints>> c 
    = (Class<List<TaskLocalConstraints>>) List.class;

But for some reason, Java doesn't like it. Tried it with String:

Laj.java:9: inconvertible types
found   : java.lang.Class<java.util.List>
required: java.lang.Class<java.util.List<java.lang.String>>
Class<List<String>> c = (Class<List<String>>) List.class;

Well, let's fool it then:

Class<List<String>> c = 
   (Class<List<String>>) (Class<?>) List.class;

It's silly, but it works. It produces an "unchecked" warning, but so does your example. Note that it doesn't result in the same class as your example, though. Your example returns the actual class of the object, namely ArrayList. This one returns List, obviously.

Sergei Tachenov
  • 24,345
  • 8
  • 57
  • 73
2

Basically, just cast around to fool the compiler. At runtime it's a simple Class anyway.

a utility method:

public static <C extends Collection, E, T extends Collection<E>>
Class<T> cast(Class<C> classC, Class<E> classE)
{
    return (Class<T>)classC;
}

Class<List<TaskLocalConstraints>> c = 
        cast(List.class, TaskLocalConstraints.class);

If you need a real Type complete with runtime generic type info, that's a different story.

irreputable
  • 44,725
  • 9
  • 65
  • 93
  • Awesome. This really works and isn't as ugly as my solution. I wonder why it works, though. I can't understand why the compiler produces no warning or error for the assignment to `c`. How does it know it is correct and safe? – Sergei Tachenov Feb 14 '11 at 12:16
  • The warning is hidden inside cast(). Same as "brute cast", it's not type safe, unless the programmer makes sure it does. For example: `Class> c = cast(List.class, String.class)` compiles, and runs. But it's really not right. – irreputable Feb 14 '11 at 13:11
1

I'm not sure if you noticed, but in your example you will get java.util.ArrayList class in "c" variable. I'm not sure if this is your point. However if we asume, that yes it is:

@SuppressWarnings("unchecked")
Class<? extends List<TaskLocalConstraints>> c = (Class<? extends List<TaskLocalConstraints>>) ArrayList.class;

However if you need list, use this:

@SuppressWarnings("unchecked")
Class<? extends List<TaskLocalConstraints>> c = (Class<? extends List<TaskLocalConstraints>>) List.class;

I added @SuppressWarnings annotation to get rid of warnings. This annotation can be used with any granularity, so you can also flag your local code with it.

The key idea in this approach is that generics are erasure. There is no information about them in runtime, to above assignments are correct.

Sebastian Łaskawiec
  • 2,667
  • 15
  • 33
1

The closest workaround I can think of is known as super type tokens. And of course someone thought of it before me ;) Depending on your context you may find the idea useful.

Cheers!

Lachezar Balev
  • 11,498
  • 9
  • 49
  • 72
0

You can get the class for List, which would be Class c = List.class. Unfortunately in Java information about generics isn't retained in runtime so after compilation your List<TaskLocalConstraints> will become simply List.

Malcolm
  • 41,014
  • 11
  • 68
  • 91
  • I know...but I am asking if there is some workaroud...on some cases its possible to get generic types even in runtime via reflection (for example to get generic types which type the current class)... – malejpavouk Feb 13 '11 at 12:23
  • I don't think this is possible. You're right that the language doesn't allow such constructs and `Class.forName` won't understand the syntax. – Malcolm Feb 13 '11 at 12:54