Java:带有类泛型的方法类型参数的工厂

时间:2015-04-24 16:47:30

标签: java generics factory

初始情况:

我为其他通用接口A<T>创建了工厂接口:

public interface Factory<T, X extends A<T>> {
  public X create();
}

问题描述:

现在我遇到的问题是我需要为每种类型 T 实例化一个工厂。这变得非常不方便,特别是如果某些代码想要从A<T>转换为A<T2>,其中 T2 是一些以前未知的类型,或者有很多不同的 T2 ,我不想为每个特例指定数百个工厂。

目标:

我想将 T 类型作为create方法的泛型参数传递。这样我得到的东西(注意,不正确的Java :-)):

public interface Factory<X extends A<?>> {
  public <T> X<T> create();
} 

Factory的实现可能只需执行以下操作:

public class Factory4B implements Factory<B> {
  public <T> X<T> create() {
    return new B<T>();
  }
} 

将以上版​​本的接口写下来会给出create:

的返回值的错误消息
  

X型不是通用的;它不能用参数

参数化

问题:

有没有办法实现这样的通用工厂,还是我需要使用完全不同的方法?我希望能够在类级别指定 X ,以便我可以轻松地实例化 X 。我不想为每个参数 T

创建一个工厂

感谢您抽出时间提前回答此问题。

根据以下评论重新思考问题(27.4.15)

根据以下评论重新思考问题,我的问题无法实现,因为无法保证通用参数仍然存在于A<T>的子类中,或者换句话说:没有通用参数的继承。

示例:

  • 让我们想一下从A<String>派生的C类。
  • 由于C没有类型参数,因此无法创建C<Integer>
  • 因此,不存在可能创建C<Integer>
  • 的一般工厂

1 个答案:

答案 0 :(得分:3)

不,仅靠仿制药是不可能的。由于“类型擦除”,T的类型在运行时不再存在,因此Java不知道要调用的构造函数。

您必须找到一种方法在运行时将T的类型传递给您的类。在Java中,您可以使用类Class<S>作为运行时类型标记。然后您的代码可能如下所示:

public <T> X<T> create(Class<T> classOfT) {
    T t = classOfT.newInstance();
    return new X<T>(t);
}