The following Java method fails to compile:
<T extends Number> void foo(T t)
{
Class<? extends T> klass = t.getClass();
}
Error received is:
Type mismatch: cannot convert from Class<capture#3-of ? extends Number>
to Class<? extends T>
Can someone explain why Class<? extends T>
is invalid, but Class<? extends Number>
is fine?
Javadoc says:
The actual result type is
Class<? extends |X|>
where |X| is the erasure of the static type of the expression on which getClass is called. For example, no cast is required in this code fragment:
Number n = 0;
Class<? extends Number> c = n.getClass();
Generics means parameterized types. The idea is to allow type (Integer, String, … etc., and user-defined types) to be a parameter to methods, classes, and interfaces. Using Generics, it is possible to create classes that work with different data types.
The short answer is, that there is no way to find out the runtime type of generic type parameters in Java. I suggest reading the chapter about type erasure in the Java Tutorial for more details. A popular solution to this is to pass the Class of the type parameter into the constructor of the generic type, e.g.
You can also use more than one type parameter in generics in Java, you just need to pass specify another type parameter in the angle brackets separated by comma.
Because the T
class' type doesn't extend from T
. Instead, it extends from Number
, exactly as you have declared yourself in <T extends Number>
. Simple as that.
A better question would be:
Why doesn't the following compile?
<T extends Number> void foo(T t) { Class<T> class1 = t.getClass(); }
The answer to that is that the Object#getClass()
returns Class<?>
with an unbounded wildcard ?
because the object itself is not directly aware about its generic type which is been expected in an arbitrary method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With