Generic factory with unknown implementation classes

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);

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)