当前位置: 首页 > 面试题库 >

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

贡可人
2023-03-14
问题内容

让我们假设两个接口:

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

public interface Fruit
{
}

现在,我要创建一个工厂FruitHandlers(例如AppleHanderOrangeHandler…),但是对于FruitHandlerFactory两个接口的实现类都不是必需的(例如在java参数化的通用静态工厂中)。本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;
    }
}

一个较小的缺点是,如果要实例化a,则必须写三遍类型名称(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);


 类似资料:
  • 我有以下静态工厂实现: FirstHandler和SecondHandler都实现以下接口: 请求对象是两个附加类的基类,其中包含请求的附加数据。 在我的主课上,我试着做以下几点: 请求的源由HTTP请求体提供,它可以解析为请求子类中的任何一个。我得到的编译错误是:“必需类型:捕获?扩展请求,提供请求”。 我知道请求对象不会扩展自身,这听起来很奇怪,但有没有办法这样调用handle方法?

  • Bootstrap包含了十几个实用工具类,各有各的目的。它们的设计用途是在你的CSS中减少高度重复的声明的频率,让开发更快捷和简单。 间距 用缩写的类向一个元素或者它的边的子集分配margin或者padding属性。包括支持单个属性、所有属性,以及垂直或水平属性。所有的类都使用全局默认的长度倍数:1rem。 外边距 .m-a-0 { margin: 0 !important; }

  • 我正在做一个单元测试,在我的应用程序中的类,它只是一个简单的类,我认为我做的一切都是正确的,但测试失败了,说: 需要但未调用:MContextWeakReference.Get();->在rahmat.com.app.utility.backwardcompatibility.StringResourceUtilTest.GetString(StringResourceUtilTest.java:

  • 我使用Delphi 10.1开发android应用程序,我使用Delphi示例实现Android26 API,当我使用通知时,它不显示。我还尝试了通知示例。但它不起作用。请帮助我实现通知,因为我需要从Android服务实现这一点。

  • TypeScript提供一些工具类型来帮助常见的类型转换。这些类型是全局可见的。 目录 Partial<T>,TypeScript 2.1 Readonly<T>,TypeScript 2.1 Record<K,T>,TypeScript 2.1 Pick<T,K>,TypeScript 2.1 Omit<T,K> Exclude<T,U>,TypeScript 2.8 Extract<T,U>,

  • 类 特征 方法 功能 StringUtils isBlank/isNotBlank 判断字符串是否为空 四、类路径加载资源文件 类所在的根路径 1、类.class.getResourceAsStream("/") 2、Thread.currentThread().getContextClassLoader().getResourceAsStream("")