我有以下课程。
public abstract class AbstractClass {
protected String value1;
public void setValue1(String value1) {
this.value1 = value1;
}
}
public abstract class ConcreteClass1 extends AbstractClass{
}
public abstract class ConcreteClass2 extends AbstractClass {
}
public class FactoryOfAbstractClass {
public AbstractClass newInstance(Class responseType) {
if (responseType == ConcreteClass1.class) {
return new ConcreteClass1();
} else if (responseType == ConcreteClass2.class) {
return new ConcreteClass2();
}
return null;
}
public abstract class ServiceClass<T extends AbstractClass> {
public T method1 (String arg1, String arg2, Class responseType) {
//Some operations resulting in a variable called value1
String value1= someOp();
T result = FactoryOfAbstractClass.newInstance(responseType);
result.setValue1(value1);
return result;
}
}
在T result = FactoryOfAbstractClass.newInstance(responseType);
中,我得到一个编译错误,说我需要对我得到的对象进行类型转换。我不理解编译错误,因为我的工厂方法返回了一个Abstract类的实例和服务类的通用T extends AbstractClass
。
一旦我把它编译成T,编译问题就消失了。但是我不明白为什么我们首先需要对它进行类型化。为什么需要进行类型转换?
另一个选择是不使用工厂而是使用responseType.newInstance()
。但内部使用反射,我想避免它们。我可以采取其他方法吗?
我不理解编译错误,因为我的工厂方法返回一个Abstract类的实例,而服务类的泛型T扩展了AbstractClass
让我们用AbstractClass
取代Car
,以获得更易理解的解释。假设程序员创建了一个ServiceClass<Mercedes>
(梅赛德斯是一种类型的汽车,对吧?)。 FactoryOfAbstractClass.newInstance()
的回归类型是Car
。因此编译器不知道此方法返回的具体Car类型。它可能是梅赛德斯,但也可能是福特,标致或Volskwagen。但是你将结果分配给T
(在这种情况下,是Mercedes
)。所以没有强制转换就无法编译。
坦白说,这家工厂完全没必要。由于调用者应该通过该类来使用,因此您可以只使用该类的实例而不是工厂,从而让调用者创建实例。或者你可以把Supplier<AbstractClass>
作为参数,而调用者只需要通过ConcreteClass1::new
。这将使代码更简单,更安全,更具可扩展性(因为您不仅限于两个已知的子类)。