Generic factory with unknown implementation classes

后端 未结 2 1131
悲&欢浪女
悲&欢浪女 2020-12-02 10:57

Let\'s assume two interfaces:

public interface FruitHandler
{
    setFruit(T fruit);
    T getFruit();
}

public interface Fruit
{
}
<         


        
2条回答
  •  遥遥无期
    2020-12-02 11:08

    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, F extends Fruit> {
        final Class handlerClass;
        final Class fruitClass;
    
        public FruitHandlerFactory(final Class handlerClass, final Class 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.class, Orange.class);
    

    You can somewhat reduce that by producing a static createFactory() method on your FruitHandlerFactory:

    static , F extends Fruit> FruitHandlerFactory createFactory(
            final Class handlerClass, final Class fruitClass) {
        return new FruitHandlerFactory(handlerClass, fruitClass);
    }
    

    and use it like this:

    FruitHandlerFactory fhf = FruitHandlerFactory.createFactory(OrangeHandler.class, Orange.class);
    

提交回复
热议问题