用Java扩展泛型的局限性,有什么办法可以解决?

时间:2018-08-29 13:09:45

标签: java generics inheritance

我有以下模型在我的应用程序中制作控制器。显然,完整模型更复杂,但是我将只关注引起问题的唯一部分:

public abstract AbstractController<T> {
    abstract protected Class<T> getType();
}

public ParentController extends AbstractController<Parent> {
    @Override
    protected Class<Parent> getType() {
        return Parent.class;
    }
}

现在,我想扩展Parent对象并为儿子提供一个控制器,它看起来像这样:

public SonController extends ParentController {
    @Override
    protected Class<Son> getType() {
        return Son.class;
    }
}

问题在于方法getType()在编译中显示不兼容(期望类Parent)。

我尝试使用泛型,但是找不到解决方案。从抽象控制器的几种方法中使用了getType方法,我真的很想避免覆盖它们。

任何想法都是好主意。

2 个答案:

答案 0 :(得分:6)

您可以更改getType返回Class<? extends T>

abstract protected Class<? extends T> getType();

然后ParentControllerSonController看起来像

public class ParentController extends AbstractController<Parent> {
    @Override
    protected Class<? extends Parent> getType() {
        return Parent.class;
    }
}

public class SonController extends ParentController {
    @Override
    protected Class<? extends Parent> getType() {
        return Son.class;
    }
}

答案 1 :(得分:5)

泛型一开始是不变的,因此无法将Class<Son>分配给Class<Parent>(在您的情况下,它们不是协变返回类型)。

但是具有扩展边界(上限)的通配符会使类型为协变,因此可以解决该问题:

public abstract class AbstractController<T> {
    abstract protected Class<? extends T> getType();
}

public class ParentController extends AbstractController<Parent> {
    @Override
    protected Class<? extends Parent> getType() {
        return Parent.class;
    }
}

class SonController extends ParentController {
    @Override
    protected Class<? extends Parent> getType() {
        return Son.class;
    }
}