I’ve defined the following classes
public class AbstractManager<E> {
public E save(E o) {
// Implementation omitted
}
public <T> T getSingleResult(Query query, Class<T> clazz) {
return clazz.cast(query.getSingleResult());
}
}
public class MatchingAlgorithmManagerImpl extends AbstractManager {
void someMethod() {
// compiler error: "Type mismatch: cannot convert from Object to Country"
Country c = this.getSingleResult(query, Country.class);
}
}
I’m very confused about why I’m getting this compiler error, surely it should be using Country as the value for <T> whereas it seems to be using Object, which I presume is the default for the <E> when I don’t specify a parametric type.
Even stranger, if I change the subclass definition to public class MatchingAlgorithmManagerImpl extends AbstractManager<Object>, the error disappears.
Why does the type I define for E have any relevance?
When you use a raw type, the compiler indeed removes all generic types, both those related to the class parameter types (
Ein your case), and those that are not (Tin your case).So when you don’t parametrise your extension, even your
Tgets erasured (is that a verb?) toObject, which explains the error.Good references can be found from Non-generic reference to generic class results in non-generic return types