使用有界泛型类扩展另一个泛型类会产生未知类型

时间:2014-11-15 00:17:46

标签: java generics

想象一下下面的类层次结构:

abstract class Train {}
class BulletTrain extends Train {}

abstract class Base<T> {}
abstract class TrainBuilder<T extends Train> extends Base<T> {}

class BulletTrainBuilder<T extends BulletTrain> extends TrainBuilder<T> {
    T getBulletTrain() {
        BulletTrain someBulletTrain;
        // Make some kind of BulletTrain and put it in someBulletTrain
        return someBulletTrain; // Compile Error: BulletTrain does not match T
    }
}

getBulletTrain内部,似乎没有返回BulletTrainBulletTrain实例的子类,因为Java发出编译错误,指出特定的子类(或BulletTrain本身)与T不匹配。

这里的某种类型信息丢失了吗?

1 个答案:

答案 0 :(得分:4)

类型信息尚未丢失,只是来自BulletTrainBuilder您无法确定TBulletTrain而不是某些子类。

例如,如果我这样做会怎么样:

BulletTrainBuilder<FastBulletTrain> builder = ... ;

调用getBulletTrain会尝试将BulletTrain转换为FastBulletTrain并抛出异常。

好像你只想这样做:

class BulletTrainBuilder extends TrainBuilder<BulletTrain> {
    public BulletTrain getBulletTrain() { ... }
}

否则,如果您需要进一步委托T层次结构,那么您就无法知道做某些事情是做什么的。您还需要委托someBulletTrain来自子类的任何地方。

例如:

abstract class AbstractTrainFactory<T extends Train> {
    protected abstract T newTrainInstance();
    public abstract T fashionTrainToSpec();
}

abstract class AbstractBulletTrainFactory<T extends BulletTrain>
extends AbstractTrainFactory<T> {
    @Override
    public T fashionTrainToSpec() {
        T theTrain = newTrainInstance();
        theTrain.noseSwoop = noseSwoopSpec;
        return theTrain;
    }
}

class FastBulletTrainFactory
extends AbstractBulletTrainFactory<FastBulletTrain> {
    @Override
    protected FastBulletTrain newTrainInstance() {
        return new FastBulletTrain();
    }
}