有没有办法在Java中获取类或实例化双重泛型类型?

时间:2012-11-19 12:37:02

标签: java generics factory-pattern nested-generics

所以说我有:

public class Foo<T> {
  // Some stuff
}

public interface Factory<T> {
  T newInstance();
  Class<T> getKlass();
}

我想制作一个Factory的实现来构建Foo&lt; T&gt; s:

public class FooFactory<T> implements Factor<Foo<T>> {
  private Class<Foo<T>> klass;
  public FooFactory(Class<Foo<T>> klass) {
    this.klass = klass;
  }

  public T newInstance() throws Exception {
    return klass.newInstance();
  }

  public Class<Foo<T>> getKlass() {
    return klass;
  }
}

两个问题:

  1. 我有什么方法可以获得一个Class&lt; Foo&lt; T&gt;&gt;如果我只有Class&lt; T&gt;?不幸的是,Foo是一个私有类,因此唯一具有全局的代码(即知道T将是什么)无法知道Foo,因此不能给我Class&lt; Foo&lt; T&gt;&gt;。< / LI>
  2. 我有更好的方法可以解决这个问题吗?
  3. 谢谢!

    P.S。对于那些要求更多细节的人,我们走了。完整的故事是Foo和FooFactory都是外部类中的私有类。 Foo在整个外部类中被广泛使用,为了避免虚假的垃圾收集,我想使用ObjectPool来实例化Foo的实例而不是新建它们并一直收集垃圾。但是,为了使用我的ObjectPool,我需要一个Factory&lt; Foo&lt; T&gt;&gt;,并且在Outer&lt; T&gt;内部。当Outer&lt; T&gt;时,我显然无法知道T将是什么。实例化。

    public class Outer<T> {
      private class Foo<T> { ... }
      private class FooFactory<T> {...}
    
      private ObjectPool<Foo<T>> fooPool;
    
      ...
    }
    

2 个答案:

答案 0 :(得分:4)

有一些方法可以为Class<Foo<T>>创建类型信息但是要做你想做的事情,你只需要在FooFactory中禁止所有泛型警告。

在运行时,Java在您编写Object的所有位置使用T,因此您可以简单地实例化Foo<Object>Foo.class,它们是相同的。这称为type erasure

泛型只是编译器的一个提示。由于您的API确保使用FooFactory的所有代码都遵循类型T,因此您可以取消警告并使用适当的强制转换,它将起作用。

注意:如果要保留类型信息,请实施the ParameterizedType interface

答案 1 :(得分:0)

只有一个Foo类对象,等于Foo.class。虽然你可以写Class<Foo<whatever>>,但这是一种欺骗性的,因为它是完全相同的Foo类对象。当然,您需要Class<Foo<T>>才能致电newInstance()并获得Foo<T>。因此,为了解决您需要Class<Foo<T>>Foo.class类型为Class<Foo>的问题,您只需进行一些投射:

public FooFactory() {
  this.klass = (Class<Foo<T>>)(Class<?>)Foo.class;
}

请注意,我们根本不需要Class<T>,因为您无需知道T即可创建Foo<T>