java - 具有未知实现类的通用工厂

标签 java generics

假设有两个接口(interface):

public interface FruitHandler<T extends Fruit>
{
    setFruit(T fruit);
    T getFruit();
}

public interface Fruit
{
}

现在我想要一个工厂来创建 FruitHandlers(例如 AppleHanderOrangeHandler、...),但是 FruitHandlerFactory 不需要知道两个接口(interface)的实现类(如 java parameterized generic static factory 中)。 FruitHandlerFactory 应该以这种方式工作(其中 OrangeHandler 实现 FruitHandlerOrange 实现 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/

相关文章:

c# - 泛型警告 T 与其他类型的类型同名

c# - 在 Ninject 中寻找通用接口(interface)的具体实现

java - 在 Java 中扩展通用接口(interface)并使其更加严格

swift - 使用通用函数获取核心数据实体亲属

java - 键入 DefaultListModel 以避免强制转换

java - onCreateView() 在第二次调用后没有显示从数据库中获取的任何数据

Java 开发人员学习企业 C++。等同于 JDBC 抽象?

java - P6Spy Spring Boot 启动装饰器产生空输出

java - While 循环不重复

java - Hibernate 不将实体链接到 Generic