Ответ 1
Так как generics в 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;
}
}
Недостатком является то, что вам нужно будет писать имена типов три раза (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) {
return new FruitHandlerFactory<H, F>(handlerClass, fruitClass);
}
и используйте его следующим образом:
FruitHandlerFactory fhf = FruitHandlerFactory.createFactory(OrangeHandler.class, Orange.class);