我有以下课程。
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);
行中,我收到一个编译错误,指出我需要对要到达T的对象进行类型转换。由于我的工厂方法正在返回,因此我不理解编译错误。抽象类的实例和服务类的通用T extends AbstractClass
。
一旦我将其转换为T,编译问题就消失了。但是我不明白为什么我们首先需要进行类型转换。为什么需要类型转换?
另一种选择是不使用工厂,而使用responseType.newInstance()
。但这在内部使用反射,我想避免它们。
我可以采取其他方法吗?
答案 0 :(得分:3)
我不理解编译错误,因为我的工厂方法正在返回Abstract类的实例,而服务类的通用T扩展了AbstractClass
让我们将AbstractClass
替换为Car
,以获得更容易理解的解释。假设程序员创建了ServiceClass<Mercedes>
(Mercedes是Car的类型,对吗?)。 FactoryOfAbstractClass.newInstance()
的返回类型为Car
。因此,编译器不知道此方法返回的Car的具体类型。它可以是梅赛德斯,但也可以是福特,标致或大众。但是,您将结果分配给T
(在本例中为Mercedes
)。因此,如果没有强制转换,就无法编译。
坦率地说,这个工厂是完全没有必要的。由于调用者应该传递该类以使用,因此您可以仅使用该类的实例而不是工厂,从而让调用者创建该实例。或者,您可以将Supplier<AbstractClass>
作为参数,而调用方只需传递ConcreteClass1::new
。这将使代码更简单,更安全和更可扩展(因为您将不仅限于两个已知的子类)。