Reputation: 15031
I have a method
public static <T, U extends T> void method(T source, T destination, Class<U> class){}
works fine with
O.method(string1, string2, string1.getClass());
But if I change the method to
public static <T> void method(T source, T destination, Class<T> myclass){}
it won't compile. Why?
Upvotes: 0
Views: 50
Reputation: 122449
The type of the result of .getClass()
is Class<? extends |X|>
, where |X|
is the erasure of the type of the expression that .getClass()
is called on. The reason for the ? extends
wildcard is that an object of a subclass of X
can be pointed to by a variable or value of type X
, and therefore, when you run .getClass()
, the class that is returned might be a subclass.
Assuming the variable string1
is of type String
, string1.getClass()
has type Class<? extends String>
, and the argument types String, String, Class<? extends String>
are not compatible with your second signature, but is compatible with your first. (Though arguably the generics in your first signature are unnecessary, because T
and U
can always be chosen to be Object
, and it wouldn't accept any fewer arguments.)
Of course, we know that the class String
is final
, so Class<? extends String>
is the same as Class<String>
, but the type system does not take that into consideration. Since you know string1
is type String
, which is final
, you can just replace that with String.class
directly.
Upvotes: 0
Reputation: 7504
object.getClass()
returns Class<?>
type where ?
is any type. Hence, for any class you can't determine the type of returned class.
More to understand below is the documentation comment of getClass method
/**
* Returns the runtime class of this {@code Object}. The returned
* {@code Class} object is the object that is locked by {@code
* static synchronized} methods of the represented class.
*
* <p><b>The actual result type is {@code Class<? extends |X|>}
* where {@code |X|} is the erasure of the static type of the
* expression on which {@code getClass} is called.</b> For
* example, no cast is required in this code fragment:</p>
*
* <p>
* {@code Number n = 0; }
* {@code Class<? extends Number> c = n.getClass(); }
* </p>
*
* @return The {@code Class} object that represents the runtime
* class of this object.
* @jls 15.8.2 Class Literals
*/
More importantly focus on The actual result type is {@code Class<? extends |X|>} where {@code |X|} is the erasure of the static type of the expression on which {@code getClass} is called.
line from documentation comment.
Upvotes: 1