I’m pretty sure something like this has been asked but I can’t really find the exact wording, so here it goes.
If I have these three classes:
package boundedtypetest;
public class Factory {
private class ClassA {}
private class ClassB extends ClassA {}
public <T extends ClassA> T create() {
return new ClassB();
}
}
Why does the Java compiler say that T
and ClassB
are incompatible in the create
method?
You've created a generic method by declaring T
as a type parameter with an upper bound. With generic methods, you must be aware that the caller can decide what T
is by passing an explicit type argument to your method.
class ClassC extends ClassA {}
ClassC c = new Factory().<ClassC>create();
There is no guarantee that the type parameter chosen by the caller, explicitly or implicitly, will match the type of what is returned, and you're returning a ClassB
. The compiler cannot guarantee type safety here so this is disallowed.
If you don't need the generics, remove the type parameter off the method and declare create
to return a ClassB
, ClassA
, or Object
.
If you need the generics, then you must take a parameter of type Class<T>
and create an instance with it to satisfy the compiler.
public <T extends ClassA> T create(Class<T> clazz) throws ReflectionRelatedExceptions
{
return clazz.getConstructor().newInstance();
}