假设有两个接口(interface):
public interface FruitHandler<T extends Fruit>
{
setFruit(T fruit);
T getFruit();
}
public interface Fruit
{
}
现在我想要一个工厂来创建 FruitHandlers
(例如 AppleHander
、OrangeHandler
、...),但是 FruitHandlerFactory
不需要知道两个接口(interface)的实现类(如 java parameterized generic static factory 中)。 FruitHandlerFactory
应该以这种方式工作(其中 OrangeHandler
实现 FruitHandler
和 Orange
实现 Fruit
):
FruitHandlerFactory fhf = new FruitHandlerFactory<OrangeHandler,Orange>();
OrangeHandler fh = fhf.create();
Orange orange = (Orange)fh.getFruit();
这应该是工厂:
public class FruitHandlerFactory<A extends FruitHandler, B extends Fruit>
{
public FruitHandler create()
{
FruitHandler<Fruit> fh = new A<B>(); //<--- ERROR
fh.setFruit(new B());
return fh;
}
}
我在哪里得到这个错误:
The type A is not generic; it cannot be parameterized with arguments <B>
顺便说一句:是否可以将 create()
方法设为静态?
最佳答案
由于 Java 中的泛型是使用删除实现的,所以 FruitHandlerFactory
的类型信息在运行时将不可用,这意味着您无法实例化 A
(或 B
) 这边。
你可以,但是传入一个正确类型的Class
对象来解决这个问题:
public class FruitHandlerFactory<H extends FruitHandler<F>, F extends Fruit> {
final Class<H> handlerClass;
final Class<F> fruitClass;
public FruitHandlerFactory(final Class<H> handlerClass, final Class<F> fruitClass) {
this.handlerClass = handlerClass;
this.fruitClass = fruitClass;
}
public H create() throws InstantiationException, IllegalAccessException {
H handler = handlerClass.newInstance();
handler.setFruit(fruitClass.newInstance());
return handler;
}
}
一个小缺点是,如果要实例化 FruitHandlerFactory
,则必须将类型名称写 3 次 (1):
FruitHandlerFactory fhf = new FruitHandlerFactory<OrangeHandler,Orange>(OrangeHandler.class, Orange.class);
您可以通过在 FruitHandlerFactory
上生成 static
createFactory()
方法来减少这种情况:
static <H extends FruitHandler<F>, F extends Fruit> FruitHandlerFactory<H, F> createFactory(
final Class<H> handlerClass, final Class<F> fruitClass) {
return new FruitHandlerFactory<H, F>(handlerClass, fruitClass);
}
并像这样使用它:
FruitHandlerFactory fhf = FruitHandlerFactory.createFactory(OrangeHandler.class, Orange.class);
关于java - 具有未知实现类的通用工厂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6093363/