如果没有强制转换

时间:2016-01-07 13:22:06

标签: java generics inheritance

首先,对于标题感到抱歉,但即使经过几分钟的思考,我发现这是最好的。情况如下:

我有一个抽象的“工厂”课程。它将T作为实例的返回类型。

abstract class Factory<T> {
    abstract T getInstance();
}

现在我添加一个界面来标记有工厂的类。该接口使用Factory本身进行参数化。

interface Factorized<TFACTORY extends Factory<?>> {}

现在我可以标记有工厂的类。

class BaseImpl1 implements Factorized<BaseImpl1Factory> {}
class BaseImpl1Factory extends Factory<BaseImpl1> {
    @Override BaseImpl1 getInstance() { return null; /* TODO */}
}

使用一个小方法和一些反射,我可以通过传递基类本身来获得工厂的实例。

<RETURNED_FACTORY extends Factory<?>> RETURNED_FACTORY getFactory(Class<? extends Factorized<RETURNED_FACTORY>> clazz) {
    /* TODO */
}

// usage:
BaseImpl1Factory factory = getFactory(BaseImpl1.class);

这种方法很好,直到我在基类中添加泛型

参见完整示例:

public class Test {
    void test() {
        getFactory(BaseImpl1.class).someMethod1();
        getFactory(BaseImpl2.class).someMethod2();     // <-- compile error
        getFactory((Class<? extends Factorized<BaseImpl2Factory>>) BaseImpl2.class).someMethod2(); // <-- it works with cast
        getFactory(SubBase2Impl.class).someMethod2();  // only for info.. this works
    }

    <RETURNED_FACTORY extends Factory<?>> RETURNED_FACTORY getFactory(Class<? extends Factorized<RETURNED_FACTORY>> clazz) {
         /* TODO */
    }
}

abstract class Factory<T> {
    abstract T getInstance();
}
interface Factorized<TFACTORY extends Factory<?>> {}

// ****** implementation without generic *******
class BaseImpl1 implements Factorized<BaseImpl1Factory> {}
class BaseImpl1Factory extends Factory<BaseImpl1> {
    void someMethod1(){}
    @Override BaseImpl1 getInstance() { /* TODO */ }
}

// ****** implementation with generic *******
class BaseImpl2<T> implements Factorized<BaseImpl2Factory> {}
class BaseImpl2Factory extends Factory<BaseImpl2<?>> {
    void someMethod2(){}
    @Override BaseImpl2<?> getInstance() { /* TODO */ }
}

class SubBase2Impl extends BaseImpl2<String>{}

当我施放它时它会起作用但我为什么要这样做?如果不进行铸造,我需要更改什么才能进入工厂?

提示:

  • 在调用getFactory()时,需要获取具体实例BaseImpl1Factory,而不仅仅是抽象Factory实例,因为工厂有不同的方法并且需要进行转换
  • 请不要关心这背后可能存在的愚蠢计划。实际上真正的问题是完全不同,但想尽可能地解决业务问题

1 个答案:

答案 0 :(得分:0)

您正在寻找名为self-type的内容。这是一个例子:

interface Factory<T> { T getInstance(); }

interface Buildable<T> { Factory<T> getFactory(); }

class CanBuild implements Buildable<CanBuild> {
  @Override
  public Factory<CanBuild> getFactory() {
    return null; // TODO
  }
}

Buildable接口(示例中为Factorized)表示可以构建T的类型。虽然T可以是任何类型,但您通常会将T与所定义的类相同,从而将其用作自我类型。

定义fluent interfaces时通常会使用自我类型。 Truth库大量使用它们,因此您可能希望查看其代码以查看更多示例。