返回与输入集合参数相同的参数集合

时间:2017-10-12 13:31:02

标签: java generics

说我有以下设置:

abstract class AbstractBaseClass {

    // Some common attributes

    AbstractBaseClass() { }

    AbstractBaseClass(AbstractBaseClass orig) {
        // Copy ctor impl
    }

    protected abstract AbstractBaseClass clone();
}

class DerivedClassA extends AbstractBaseClass {

    // Some specialized attributes

    DerivedClassA() { }

    DerivedClassA(DerivedClassA orig) {
        super(orig);
        // Copy ctor impl
    }

    List<DerivedClassB> subObjects = new ArrayList<>();

    protected DerivedClassA clone() {
        return new DerivedClassA(this);
    }

}

class DerivedClassB extends AbstractBaseClass {

    // Some specialized attributes

    DerivedClassB() { }

    DerivedClassB(DerivedClassB orig) {
        super(orig);
        // Copy ctor impl
    }

    List<DerivedClassC> subObjects = new ArrayList<>();

    protected DerivedClassB clone() {
        return new DerivedClassB(this);
    }

}

// DerivedClassC implemented the same way

现在我想在我的抽象基类中实现一个泛型方法 克隆其中一个派生类中包含的给定主题列表:

abstract class AbstractBaseClass {

    // Other stuff, see above

    // Doesn't work because of type issues
    protected <T> List<T> cloneList(List<? extends AbstractBaseClass> origList) {
        if (origList == null) return null;

        List<T> result = new ArrayList<>();
        for (AbstractBaseClass i: origList) {
            result.add(i.clone());
        }

        return result;
    }
}

现在我想调用此方法如下:

class DerivedClassA extends AbstractBaseClass {

    // Other stuff

    List<DerivedClassB> subObjects;

    DerivedClassA(DerivedClassA orig) {
        super(orig);
        // Copy ctor impl
        subObjects = cloneList(orig.subObjects);
    }        

}

现在我期望的是cloneList(...)AbstractBaseClass的实现返回一个与参数列表具有相同类型的列表,因此我可以将它们存储在我的派生类中。我该怎么办呢?

到目前为止我发现的是我可以这样实现cloneList(...)

protected List<AbstractBaseClass> cloneList(List<? extends AbstractBaseClass> origList) {
    // null check...

    List<AbstractBaseClass> result = new ArrayList<>();
    for (AbstractBaseClass i: origList) {
        result.add(i.clone());
    }

    return result;
}

然后在我的派生类中使用强制转换:

DerivedClassA(DerivedClassA orig) {
    super(orig);
    // Copy ctor impl
    List<AbstractBaseClass> tmp = cloneList(orig.subObjects);
    for (DerivedClassA i: tmp) {
        subObjects.add( (DerivedClassA) i );
    }
}    

但这对我来说并不是很令人满意,因为我希望在获取AbstractBaseClass类型的对象的克隆集合之后,有一个不依赖于强制转换的通用实现

1 个答案:

答案 0 :(得分:0)

您可以更改以下行:

abstract class AbstractBaseClass<T extends AbstractBaseClass<T>>

protected List<T> cloneList(List<T> origList) {
    if (origList == null)
        return null;

    List<T> result = new ArrayList<T>();
    for (T i : origList) {
        result.add(i.clone());
    }

    return result;
}

和派生类

class DerivedClassA extends AbstractBaseClass<DerivedClassA>

DerivedClassA(DerivedClassA orig) {
    super(orig);

    List<DerivedClassA> clonedList = cloneList(orig.subObjects);
    subObjects.addAll(clonedList);
}

最后你不需要施放任何东西。