具有未知实现类的通用工厂 [英] Generic factory with unknown implementation classes
问题描述
我们假设有两个接口:
public interface FruitHandler< T extends Fruit>
{
setFruit(T fruit);
T getFruit();
}
public interface Fruit
{
}
现在我想要一个工厂创建 FruitHandlers
(例如 AppleHander
, OrangeHandler
,...),但是 FruitHandlerFactory
并不知道这两个接口的实现类的必要性(如java参数化泛型静态工厂)。 FruitHandlerFactory
应该以这种方式工作(其中 OrangeHandler
实现 FruitHandler
和 Orange
执行 Fruit
):
FruitHandlerFactory fhf = new FruitHandlerFactory< OrangeHandler,Orange>();
OrangeHandler fh = fhf.create();
橙色橙色=(橙色)fh.getFruit();
这应该是工厂:
public class FruitHandlerFactory< A extends FruitHandler,B extends Fruit>
{
public FruitHandler create()
{
FruitHandler< Fruit> fh = new A< B>(); //< ---错误
fh.setFruit(new B());
返回fh;
我得到这个错误:
类型A不是通用的;它不能用参数< B>来参数化。
顺便说一下:是否可以使 create()
method static?
由于Java中的泛型是使用擦除来实现的,所以 FruitHandlerFactory
在运行时不可用,这意味着你不能实例化 A
(或者 B $ c $
You can ,但传入 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()抛出InstantiationException,IllegalAccessException {
H handler = handlerClass.newInstance();
handler.setFruit(fruitClass.newInstance());
返回处理程序;
}
}
一个小缺点是您必须编写类型名称三次(1)如果你想实例化一个 FruitHandlerFactory
:
FruitHandlerFactory fhf = new FruitHandlerFactory< OrangeHandler,Orange>(OrangeHandler.class,Orange.class);
通过产生一个 static
createFactory()
方法在您的 FruitHandlerFactory
:
static< H extends FruitHandler< F>,F extends Fruit> FruitHandlerFactory< H,F> createFactory(
final Class< H> handlerClass,final Class< F> fruitClass){
返回新的FruitHandlerFactory< H,F>(handlerClass,fruitClass);
}
并像这样使用它:
FruitHandlerFactory fhf = FruitHandlerFactory.createFactory(OrangeHandler.class,Orange.class);
Let's assume two interfaces:
public interface FruitHandler<T extends Fruit>
{
setFruit(T fruit);
T getFruit();
}
public interface Fruit
{
}
Now I want a factory to create FruitHandlers
(e.g. AppleHander
, OrangeHandler
, ...), but the FruitHandlerFactory
does not know neccessary about the implementing classes of both interfaces (like in java parameterized generic static factory). The FruitHandlerFactory
should work in this way (where OrangeHandler
implements FruitHandler
and Orange
implements Fruit
):
FruitHandlerFactory fhf = new FruitHandlerFactory<OrangeHandler,Orange>();
OrangeHandler fh = fhf.create();
Orange orange = (Orange)fh.getFruit();
This should be the factory:
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;
}
}
Where I get this error:
The type A is not generic; it cannot be parameterized with arguments <B>
BTW: Is it possible to make the create()
method static?
Since generics in Java are implemented using erasure, the type information of FruitHandlerFactory
will not be available at runtime, which means you can't instantiate A
(or B
) this way.
You can, however pass in a Class
object of the correct type to work around this:
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;
}
}
A minor drawback is that you'll have to write the type names three times(1) if you want to instantiate a FruitHandlerFactory
:
FruitHandlerFactory fhf = new FruitHandlerFactory<OrangeHandler,Orange>(OrangeHandler.class, Orange.class);
You can somewhat reduce that by producing a static
createFactory()
method on your FruitHandlerFactory
:
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);
}
and use it like this:
FruitHandlerFactory fhf = FruitHandlerFactory.createFactory(OrangeHandler.class, Orange.class);
这篇关于具有未知实现类的通用工厂的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!