My code:
private static <T> T get(Class<T> clazz) throws IllegalAccessException, InstantiationException {
if (clazz.equals(String.class)) {
return (T) new String("abc");//line x
} else {
return clazz.newInstance();
}
}
As you see, in line x
, T
have to be String.class
and returns String
. But compile failed without casting the result to T
.
Change line x
to return new String("abc");
results Incompatible types
.
I guess most developers heard the guideline stating that, when designing methods, you should return the most specific type and accept the most generic one. Is it always applicable? Let’s try to look at it from different perspectives. Let’s start with some simple example. Let’s say we have the following class hierarchy: And the following method:
Of course, it’s not always possible to use generic types for input parameters. Otherwise, we would always use Object as the type of the method parameters. That brings us to the second part of the guideline: make your methods accept parameters of the most generic types possible.
It is not always possible to return a value of a specific type (e.g. Employee or Customer). For example, if you have some polymorphic collection with objects of both types, you might have no choice other than returning an object of Person type:
Changing the return value type to a more generic one puts too many restrictions to the method consumers. In the worst case, the client code would need to manually cast the Person object to an Employee, so it is better to not make them do that. It is not always possible to return a value of a specific type (e.g. Employee or Customer).
The compiler does not take into account the if
statement.
So all it sees is that you need to return a T
(of which it has no further knowledge). It did not infer that T
must be String
here.
You can avoid the warning that you get for the "unchecked cast to erased type" by doing
return clazz.cast("abc");
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