所以说我有:
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;
}
}
两个问题:
谢谢!
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;
...
}
答案 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>
。