返回的绑定类型与匹配该绑定的类型不兼容



我很确定有人问过这样的问题,但我真的找不到确切的措辞,所以就这样吧。

如果我有这三个类:

package boundedtypetest;
public class Factory {
private class ClassA {}
private class ClassB extends ClassA {}
public <T extends ClassA> T create() {
return new ClassB();
}
}

为什么Java编译器说TClassBcreate方法中不兼容?

通过将T声明为具有上界的类型参数,您创建了一个泛型方法。对于泛型方法,您必须知道,调用者可以通过向方法传递显式类型参数来决定什么是T

class ClassC extends ClassA {}
ClassC c = new Factory().<ClassC>create();

不能保证调用者显式或隐式选择的类型参数将与返回的类型匹配,并且您返回的是ClassB。编译器不能保证这里的类型安全,因此这是不允许的。

如果不需要泛型,请从方法中移除类型参数,并声明create以返回ClassBClassAObject

如果您需要泛型,那么您必须获取类型为Class<T>的参数,并用它创建一个实例以满足编译器的要求。

public <T extends ClassA> T create(Class<T> clazz) throws ReflectionRelatedExceptions 
{
return clazz.getConstructor().newInstance();
}

问题是您将能够将ClassB存储在另一个扩展ClassA的类中

例如,您有一个ClassC,它与ClassB一样扩展了ClassA,您可以将create()的结果存储在ClassC对象中,但该方法能够返回ClassB实例?这就是为什么你不能

class Factory {
void method() {
ClassC c = create();     //This is correct, regarding the return type of the method
}                            // But it would allow to store ClassB in ClassC : NOPE
public <T extends ClassA> T create() {
return new ClassB();
}
private class ClassA { }
private class ClassB extends ClassA { }
private class ClassC extends ClassA { }
}
这是因为T可以是ClassA的任何子类。举例来说,假设您有另一个扩展ClassA的类ClassC
class ClassC extends ClassA {
}

现在,您永远无法确定ClassA的哪个子类将用于调用此方法。

class Factory {
public <T extends ClassA> T create() {
return new ClassB();
}
}

这里的T可以是ClassBClassC等。因此,您不可能返回ClassA的一个可能的子类

详细信息可在此SO问题中找到。

最新更新