In such a function:

<T> void foo(T obj)

The type of obj.getClass() is Class<?> and not Class<? extends T>. Why?

The following code works fine:

String foo = "";
Class<? extends String> fooClass = foo.getClass();

So the signature of T#getClass() seems to return a Class<? extends T>, right?

Why is the signature different if T really is a generic?

To overcome the problem (and to make it more clear what I wander about), I have implemented this function:

@SuppressWarnings("unchecked") static <T> Class<? extends T> classOf(T obj) {
    return (Class<? extends T>) obj.getClass();
}

Again the question: Why is the cast needed here and not in the String case? And why is the SuppressWarnings needed? Isn't it always clear from the code that it will always be able to safely do this cast?

Is there any way I can get a Class<? extends T> from obj? If yes, how? If not, why not?

One way would be to use classOf. That would be safe, right? If that is always safe and gives a safe way to really get a Class<? extends T> (instead of a Class<?>), why is there no such function in Java? Or is there?


How about that case:

<T> void bar(T[] array)

array.getClass().getComponentType() again returns a Class<?> and not a Class<? extends T>. Why?

I have implemented this function:

@SuppressWarnings("unchecked") static <T> Class<? extends T> classOf(T[] array) {
    return (Class<? extends T>) array.getClass().getComponentType();
}

Is this again safe to use?


Edit
Report