Factory方法,用于实例化泛型类中使用的对象的实例

问题描述 投票:1回答:1

我有以下课程。

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()。但内部使用反射,我想避免它们。我可以采取其他方法吗?

java generics factory generic-programming
1个回答
3
投票

我不理解编译错误,因为我的工厂方法返回一个Abstract类的实例,而服务类的泛型T扩展了AbstractClass

让我们用AbstractClass取代Car,以获得更易理解的解释。假设程序员创建了一个ServiceClass<Mercedes>(梅赛德斯是一种类型的汽车,对吧?)。 FactoryOfAbstractClass.newInstance()的回归类型是Car。因此编译器不知道此方法返回的具体Car类型。它可能是梅赛德斯,但也可能是福特,标致或Volskwagen。但是你将结果分配给T(在这种情况下,是Mercedes)。所以没有强制转换就无法编译。

坦白说,这家工厂完全没必要。由于调用者应该通过该类来使用,因此您可以只使用该类的实例而不是工厂,从而让调用者创建实例。或者你可以把Supplier<AbstractClass>作为参数,而调用者只需要通过ConcreteClass1::new。这将使代码更简单,更安全,更具可扩展性(因为您不仅限于两个已知的子类)。

© www.soinside.com 2019 - 2024. All rights reserved.